简体   繁体   English

等待异步操作的结果

[英]Wait for result of async operation

I had such API for async requests 我有这样的API用于异步请求

 request(pathParams, params, method, callback, error) {

        ...........

        return $.ajax({
            ...requestAttrs,
            url: url,
            data: params,
            xhrFields: {
                withCredentials: true
            },
            type: method,

            success: callback,
            error: error
        })
    }

But due to some requirements I need to change it to 但是由于某些要求,我需要将其更改为

request(pathParams, params, method, callback, error) {

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

                success: callback,
                error: error
            })      

            })

        }

I hope you see my problem. 我希望你看到我的问题。 In the previous case I was using the value returned from $.ajax call - for example because I would cancel those requests. 在前一种情况下,我使用了$.ajax调用返回的值-例如,因为我将取消这些请求。

But now when I need to put my ajax function inside another async function, I can't return the $.ajax value like I did previously (because now I moved return inside someAsyncFunction ). 但是现在当我需要将ajax函数放入另一个异步函数中时,我无法像以前一样返回$ .ajax值(因为现在我将return移动到了someAsyncFunction内部)。

Is there a way I could possibly first run that someAsyncFunction inside request, wait for its completion and then return $.ajax as I was doing before? 有没有办法我可以先在请求中运行someAsyncFunction ,等待其完成,然后像以前一样返回$.ajax

is something like stratified.js library usable for this? 像stratified.js库这样可用于此吗?


someAsyncFunction is updateToken function from here . someAsyncFunction是来自此处的 updateToken函数。 Basically I need to put what I had in request before, inside the success callback of updateToken - but the problem is I can't return the $ajax now as I did before. 基本上,我需要将之前request放入updateToken的成功回调中,但是问题是我现在不能像以前那样返回$ajax

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 创建someAsyncFunction并根据需要进行判断,然后返回其值

  2. Same applies to your ajax call. 同样适用于您的ajax调用。 In case it needs the output from someAsyncFunction then it's very easy to send them as well 如果需要来自someAsyncFunction的输出,那么也很容易发送它们

  3. Promise for the win! 承诺胜利! Chain all your calls and keep your code's flow :) 链接所有调用并保持代码流:)

I'm using setTimeout so they look asynchronous 我正在使用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') 

Sample code someAsyncFunction and keycloak thing :) 示例代码someAsyncFunctionkeycloak东西:)

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

OK, I see where your problem is. 好的,我知道您的问题出在哪里。 Apologies for not thinking it through. 道歉没有考虑清楚。 The jqXHR that $.ajax returns functions in two ways: both as a promise, and also as a handle where you can abort it before it is done. $.ajax返回的jqXHR以两种方式起作用:既作为承诺,又作为可以在完成之前中止它的句柄。 The first requires we return it, so that we can continue the promise chain. 第一个要求我们返回它,以便我们可以继续承诺链。 The second requires we retain it, so we can get at it outside the promise chain. 第二个要求我们保留它,以便我们可以在承诺链之外实现它。

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();

EDIT: allowed aborting before AJAX. 编辑:允许在AJAX之前中止。

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. 在这里,我只是返回了一个字符串,您可以编辑以返回ajax请求。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM