foreach中的异步/等待不等待

Tom*_*you 11 javascript async-await

我正在尝试在使用循环的函数中使用async和。烦人的是我无法让它工作。应该发生的是它需要一个 event 数组,遍历它们,添加一些额外的数据,然后将它们推送到数组中。然后从原始函数返回该数组。这是我的代码:awaitforEachdocseventsevents

async function getEvents() {
  ...
  var events = []
  await addExtrasToDocsForUser(docs, currentUserId, events)
  return events

}


var addExtrasToDocsForUser = (docs, currentUserId, events) => {
    return docs.forEach(async (eventDoc) => {
        const event = await addExtrasToDocForUser(eventDoc, currentUserId)
        events.push(event)
    })
}
Run Code Online (Sandbox Code Playgroud)

实际发生的是该getEvents()函数eventsforEach循环完成之前作为一个空数组返回。我该如何解决?

Nin*_*liu 11

基本上,这就是里面发生的事情forEach

Array.prototype.forEach = function (callback) {
  for (let index = 0; index < this.length; index++) {
    callback(this[index], index, this);
  }
};
Run Code Online (Sandbox Code Playgroud)

实际上,真正的实现如下,但底线是我们不等待回调完成,因此使用返回 Promise 的函数不会每次都等待 Promise 解析。

您的代码不完整且不可验证,因此我无法确定以下内容是否有效,但它可能应该按照您的预期运行:

const addExtrasToDocsForUser = async (docs, currentUserId, events) => {
  for (let i=0; i<docs.length; i++) {
    const event = await addExtrasToDocForUser(docs[i], currentUserId);
    events.push(event);
  }
  return;
}
Run Code Online (Sandbox Code Playgroud)

您可能还想查看有关 foreach + async/await 的 CodeBurst 文章


jo_*_*_va 9

使用Promise.allmap获取所有内部承诺并返回一个等待所有内部承诺的承诺:

const addExtrasToDocsForUser = async (docs, currentUserId, events) => {
    return Promise.all(docs.map(async (eventDoc) => {
        const event = await addExtrasToDocForUser(eventDoc, currentUserId)
        events.push(event)
    }));
}
Run Code Online (Sandbox Code Playgroud)


Mir*_*rCZ 2

为什么要结合同步和异步功能?
您调用了await addExtrasToDocsForUser(docs, currentUserId, events),但您的函数 addExtrasToDocsForUser 没有调用async

var addExtrasToDocsForUser = async (docs, currentUserId, events) => {
  return await docs.forEach(async (eventDoc) => {
    const event = await addExtrasToDocForUser(eventDoc, currentUserId)
    events.push(event)
  })
}
Run Code Online (Sandbox Code Playgroud)

你想做这样的事情:

var addExtrasToDocsForUser = async (docs, currentUserId, events) => {
  return await docs.forEach(async (eventDoc) => {
    const event = await addExtrasToDocForUser(eventDoc, currentUserId)
    events.push(event)
  })
}
Run Code Online (Sandbox Code Playgroud)