JavaScript:while 循环中的异步方法 [英] JavaScript: Asynchronous method in while loop

查看:22
本文介绍了JavaScript:while 循环中的异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个项目,该项目要求我通过 API 方法调用使用 JavaScript.我是一名 Java 程序员,之前从未从事过 Web 开发,所以我遇到了一些麻烦.

I'm tackling a project that requires me to use JavaScript with an API method call. I'm a Java programmer who has never done web development before so I'm having some trouble with it.

此 API 方法是异步的,并且处于 while 循环中.如果它返回一个空数组,while 循环结束.否则,它会循环.代码:

This API method is asynchronous and it's in a while loop. If it returns an empty array, the while loop finishes. Otherwise, it loops. Code:

var done = true;

do
{
    async_api_call(
        "method.name", 
        { 
            // Do stuff.
        },
        function(result) 
        {
            if(result.error())
            {
                console.error(result.error());
            }
            else
            {
                // Sets the boolean to true if the returned array is empty, or false otherwise.
                done = (result.data().length === 0) ? true : false;
            }
        }
    );

} while (!done);

这不起作用.循环在done"的值被更新之前结束.我已经对这个主题进行了一些阅读,似乎我需要使用承诺或回调,因为 API 调用是异步的,但我不明白如何将它们应用到我上面的代码中.

This doesn't work. The loop ends before the value of "done" is updated. I've done some reading up on the subject and it appears I need to use promises or callbacks because the API call is asynchronous, but I can't understand how to apply them to the code I have above.

将不胜感激!

推荐答案

看到底部,有真正的答案.

我鼓励您使用 Promise API.您的问题可以使用 Promise.all 调用来解决:

edit: see the bottom, there is the real answer.

I encourage you yo use the Promise API. Your problem can be solved using a Promise.all call:

let promises = [];
while(something){
    promises.push(new Promise((r, j) => {
        YourAsyncCall(() => r());
    });
}
//Then this returns a promise that will resolve when ALL are so.
Promise.all(promises).then(() => {
    //All operations done
});

语法在 es6 中,这里是 es5 等价物(Promise API 可能包含在外部):

The syntax is in es6, here is the es5 equivalent (Promise API may be included externally):

var promises = [];
while(something){
    promises.push(new Promise(function(r, j){
        YourAsyncCall(function(){ r(); });
    });
}
//Then this returns a promise that will resolve when ALL are so.
Promise.all(promises).then(function(){
    //All operations done
});

你也可以让你的api调用返回promise并将其直接推送到promise数组中.

You can also make your api call return the promise and push it directly to the promise array.

如果您不想编辑 api_call_method,您可以随时将代码包装在一个新的 Promise 中,并在它完成时调用方法 resolve.

If you don't want to edit the api_call_method you can always wrap your code in a new promise and call the method resolve when it finishes.

编辑:我现在看到了你代码的重点,抱歉.我刚刚意识到 Promise.all 不会解决问题.

edit: I have seen now the point of your code, sorry. I've just realized that Promise.all will not solve the problem.

你应该把你发布的内容(不包括while循环和控制值)放在一个函数中,并根据条件再次调用它.

You shall put what you posted (excluding the while loop and the control value) inside a function, and depending on the condition calling it again.

然后,可以将所有内容都包装在一个 Promise 中,以使外部代码知道此异步执行.稍后我会在我的 PC 上发布一些示例代码.

Then, all can be wraped inside a promise in order to make the external code aware of this asynchronous execution. I'll post some sample code later with my PC.

您可以使用 promise 来控制应用程序的流程并使用递归代替 while 循环:

You can use a promise to control the flow of your application and use recursion instead of the while loop:

function asyncOp(resolve, reject) {
    //If you're using NodeJS you can use Es6 syntax:
    async_api_call("method.name", {}, (result) => {
      if(result.error()) {
          console.error(result.error());
          reject(result.error()); //You can reject the promise, this is optional.
      } else {
          //If your operation succeeds, resolve the promise and don't call again.
          if (result.data().length === 0) {
              asyncOp(resolve); //Try again
          } else {
              resolve(result); //Resolve the promise, pass the result.
          }
      }
   });
}

new Promise((r, j) => {
    asyncOp(r, j);
}).then((result) => {
    //This will call if your algorithm succeeds!
});

/*
 * Please note that "(...) => {}" equivals to "function(...){}"
 */

这篇关于JavaScript:while 循环中的异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆