等待异步操作的结果

时间:2018-01-11 08:12:11

标签: javascript ajax asynchronous

我有异步请求的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值(因为现在我在someAsyncFunction内移动了返回。)

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

类似于stratified.js库吗?

someAsyncFunction来自hereupdateToken功能。基本上我需要把request之前的内容放在updateToken的成功回调中 - 但问题是我现在不能像以前那样返回$ajax

3 个答案:

答案 0 :(得分:2)

I took the liberty to change your code a little bit.

My approach is to separate code as much as possible so you don't get into the Callback Hell.

  1. Create someAsyncFunction and make whatever you judge necessary so then you can return its value

  2. Same applies to your ajax call. In case it needs the output from someAsyncFunction then it's very easy to send them as well

  3. Promise for the win! Chain all your calls and keep your code's flow :)

I'm using setTimeout so they look asynchronous

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')

Sample code someAsyncFunction and keycloak thing :)

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

答案 1 :(得分:2)

好的,我知道你的问题在哪里。抱歉不考虑它。 $.ajax以两种方式返回函数的jqXHR:作为promise,也作为句柄,你可以在它完成之前中止它。第一个要求我们返回它,以便我们可以继续承诺链。第二个要求我们保留它,所以我们可以在承诺链之外得到它。

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之前中止。

答案 2 :(得分:-1)

You may want to do like this. Hope this fits your case. If I misunderstood it, pls ping in the comment.

Here, I just returned a string, you can edit to return the ajax request.

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

console.log(request());