异步/等待foreach不等待

时间:2019-02-05 10:33:43

标签: javascript

我正在尝试在使用async循环的函数中使用awaitforEach。令人讨厌的是我无法正常工作。应该发生的是,它需要事件docs的数组,循环遍历它们,添加一些额外的数据,然后将它们推入events数组。然后,此events数组从原始函数返回。这是我的代码:

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

实际发生的是getEvents()函数在events循环完成之前以空数组的形式返回forEach。我该如何解决?

3 个答案:

答案 0 :(得分:1)

基本上,这是在forEach内部发生的事情:

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

实际上,真正的实现是the following,但最重要的是我们不等待回调完成,因此使用返回promise的函数不会等待每次解决的诺言。

您的代码不是complete and verifiable,所以我不确定以下代码是否有效,但是它可能会发挥您的期望:

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;
}

您可能还需要检查this CodeBurst article on foreach + async/await

答案 1 :(得分:0)

使用s = 'jeremy' o = {'s':'gordon'} a = [s,o] console.log(typeof(a[0])) // string console.log(typeof(a[1])) //object Promise.all获得所有内在的诺言,并返回等待它们的单个诺言:

map

答案 2 :(得分:0)

为什么要组合同步和异步功能?
您调用了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)
  })
}

您想要执行以下操作:

var someOperation = async (op0, op1) => {
	return op0+':'+op1
}

var fnWithForeach = async (docs, number, outputs)=>{
  return await docs.forEach(async (doc)=>{
	const output = await someOperation(doc, number)
	outputs.push(output) 
  })
}

async function getOutputs() {
  // ...
  var docs = ['A', 'B', 'C']
  var number = 10
  // ...
  var outputs = []
  await fnWithForeach(docs, number, outputs)
  return outputs
}

async function main() {
  // ...
  var outputs = await getOutputs()
  console.log(outputs)
  // ...
}

main()