等待异步操作的结果



我有这样的 API 用于异步请求

 request(pathParams, params, method, callback, error) {
        ...........
        return $.ajax({
            ...requestAttrs,
            url: url,
            data: params,
            xhrFields: {
                withCredentials: true
            },
            type: method,
            success: callback,
            error: error
        })
    }

但是由于某些要求,我需要将其更改为

request(pathParams, params, method, callback, error) {
            ...........
            someAsyncFunction(function(){
                return $.ajax({
                ...requestAttrs,
                url: url,
                data: params,
                xhrFields: {
                    withCredentials: true
                },
                type: method,
                success: callback,
                error: error
            })      
            })
        }

我希望你看到我的问题。在前一种情况下,我使用的是从调用返回的值$.ajax例如,因为我会取消这些请求。

但是现在当我需要将我的 ajax 函数放在另一个异步函数中时,我不能像以前那样返回 $.ajax 值(因为现在我将 return 移到了 someAsyncFunction 中(。

有没有办法我可以先在请求中运行该someAsyncFunction,等待其完成,然后像以前一样返回$.ajax

像分层.js库这样的东西可以用于这个吗?


someAsyncFunction从这里开始updateToken功能。基本上我需要将我之前在request中的内容放在updateToken的成功回调中 - 但问题是我现在无法像以前那样返回$ajax

我冒昧地稍微更改了一下您的代码。

我的方法是尽可能多地分离代码,这样你就不会陷入回调地狱。

  1. 创建someAsyncFunction并制作您认为必要的任何内容,以便您可以返回其值

  2. 这同样适用于您的ajax通话。如果它需要someAsyncFunction的输出,那么发送它们也很容易

  3. 承诺获胜!链接所有调用并保持代码流:)

我正在使用setTimeout所以它们看起来是异步的

function someAsyncFunction() {
  return new Promise(resolve =>
    setTimeout(() => {
      console.log('-> someAsyncFunction has finished')
      
      const token = 'abc123'
      resolve(token)
    }, 1000)
  ) 
}
function executeAjaxRequest(pathParams, params, method, token) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('-> executeAjaxRequest has finished')
      resolve()
    }, 2000)
  })
}
function request(pathParams, params, method) {
  someAsyncFunction()
    .then((token) => executeAjaxRequest(pathParams, params, method, token))
    .then(() => console.log('-> end!'))
}
request('pathParams', 'params', 'method')

示例代码someAsyncFunctionkeycloak事情:)

function someAsyncFunction() {
  return new Promise((resolve, reject) => {
    keycloak.updateToken(30)
      .success(resolve)
      .error(reject)
  })
}

好的,我知道你的问题在哪里。很抱歉没有考虑清楚。$.ajax返回的 jqXHR 以两种方式运行:既作为承诺,又作为句柄,您可以在完成之前中止它。第一个要求我们退回它,这样我们才能继续承诺链。第二个要求我们保留它,这样我们就可以在承诺链之外得到它。

function authenticateWithKeycloak() {
  return new Promise((resolve, reject) => {
    keycloak.updateToken(30)
      .success(resolve)
      .error(reject)
  })
}    
function request(...) {
  let promise = authenticateWithKeycloak();
  promise.abort = () => { promise.aborted = true; }
  return promise.then(authenticated => {
    if (!promise.aborted) {
      let xhr = $.ajax({...});
      promise.abort = () => xhr.abort();
    }
    return promise;
  })
}
let reqPromise = request(...);
reqPromise.then(...);
reqPromise.abort();

编辑:允许在AJAX之前中止。

你可能想这样做。希望这适合您的情况。如果我误解了它,请在评论中ping。

在这里,我刚刚返回了一个字符串,您可以编辑以返回 ajax 请求。

function someAsyncFunction(callback)
{
    //do something
    
    return callback();
}
function request(pathParams, params, method, callback, error) {
    return someAsyncFunction(function(){
            return "Ajax request";    
    });
}
console.log(request());