如何在JavaScript的array.forEach中等待异步函数

7
我正在尝试在foreach中进行async请求,以便稍后使用数据,但对我来说无效。
我知道Array.Foreach是同步函数,所以我甚至尝试了$.when.done,但它仍然不会等待直到完成。
如果这是单个值,我本可以使用回调,但现在它是一个数组。有没有更好的方法通过回调处理这个问题,以实现在继续之前等待async请求?
browseItems.forEach((browseItem: any) => {

   AsynchFunction();

   cosole.log("Step 2")  
}
function AsynchFunction(){
   console.log("Step 1")
}

我正在尝试获得以下输出:
步骤1
步骤2
3个回答

9

@basarat的答案的基础上,我发现如果你正在使用TypeScript中的async/await功能(自TS 1.7需要ES6目标),这个方法非常有效:

async function processData(data: any[]) {
  const promises = data.map(async (item) => {
    await doSomeAsyncStuff(item);
    //you can do other stuff with the `item` here
  });
  await Promise.all(promises);

  //you can continue with other code here that will execute after all the async code completes
}

async function doSomeAsyncStuff(value) {
  return new Promise((resolve, reject) => {
    //call some async library or do a setTimeout and resolve/reject the promise
  });
}

更新:现在在TypeScript的主分支中,asyncawait已经可用于目标为ES5的TypeScript代码,即将发布的TypeScript 2.1版本也一样。您可以使用npm install --save-dev typescript@next安装它。
更新:此功能在当前版本的TypeScript中适用于所有ES目标。唯一需要注意的是,如果您的目标是ES5或ES3,则需要提供一个Promise polyfill,否则代码将在旧版浏览器上失败。

这看起来很整洁,但似乎实际上并不起作用。首先,你需要从 map 返回一些东西......但即使那样,它似乎也不会在此之后等待。 - dcsan
@dcsan,在TypeScript中,当您await返回Promise的函数时,包含的async函数会自动返回一个Promise,即使该Promise是Promise<void>。您不需要从.map函数中返回任何内容。我已经多次使用这种模式,它运行良好。 - Joe Skeen

6
如果您正在使用 Promises,可以使用像 `Promise.all` 这样的函数来处理异步请求等待。是否有更好的方法通过回调来实现在移动到下一个步骤之前等待异步请求的处理呢?
var promises = browseItems.map((browseItem: any) => AsynchFunction());
Promise.all(promises).then((values)=>{});

2

一旦您开始使用异步函数,您可以选择使用 回调函数Promise。在上面的代码中,您只需要定义一个回调函数,在异步函数返回后调用该函数。请参见以下示例:

browseItems.forEach((browseItem: any) => {
   AsynchFunction(postProcess);   
}
function AsynchFunction(callback){
   console.log("Step 1");
   if(asyncProcessDone){
       callback();
   }
}
function postProcess(){
    console.log("Step 2")
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接