如何在forEach中调用promise?

我有事件stream向下面的程序,所以基于事件的价值我触发不同的承诺,所以我想检查是否它的好主意内使用承诺forEach。

用下面的代码,当我有事件element.variables.caseIdFound值永远不会满足条件。 任何想法什么是执行错误我是相当新的承诺。 任何与以下代码的例子高度赞赏。

camunda.js

  var caseIdFound; var processingCompleted; function checkTicketNum(element) { var EventCasesID; var event; var ticketNumber; var CasesID; var insertIDBEvents = []; var event; return new Promise(function(resolve, reject) { event = JSON.parse(element.variables.event.value); ticketNumber = event.body.raw.tkt; CasesID = event.body.raw.CasesIDuuid; controller.insertCase(ticketNumber, function(err, response) { event.body.raw.LogIDuuid = generateUUID(); if (response.length == 0) { completeTask('TicketNotFOund',element.id); } else { EventCasesID = response[0].CasesID; if(CasesID === EventCasesID) { caseIdFound = true; completeTask(element.id,caseIdFound); processingCompleted = true; resolve(processingCompleted); } } }) }); } function postIDBCall(element) { var event; return new Promise( function(resolve, reject) { event = JSON.parse(element.variables.event.value); controller.insertTicketAndCase2(event.body.raw, function(err, response2) { controller.insertTicketAndCase(event.body.raw, function(err, response1) { completeTask(event.id); console.log("InsertIDB Result Completed",element.id); processingCompleted = true; resolve(processingCompleted); }) }) }); } module.exports = { checkTicketNum: checkTicketNum, generateUUID: generateUUID, completeTask: completeTask }; 

promise.js

  var camunda = require('./camunda'); data.forEach(function(element) { if (!element.variables.caseIdFound) { camunda.checkTicketNum(element).then(function(processingCompleted) { console.log('1st Box', processingCompleted); }); }else if(element.variables.caseIdFound) { console.log('END BOX IF', element.variables.caseIdFound); camunda.postIDBCall(element).then(function(processingCompleted){ console.log('2nd Box', processingCompleted); }); } }); 

编辑:感谢@Bergi的意见。 有一个错误,你仍然需要Promise.all()。然后()

这里是@serendipity代码的ES8版本:

 const data = [false, 10, 20, 30] const { checkTicketNum, postIDBCall } = require("./camunda") const result = data.map(async(pieceOfData) => { return (!pieceOfData) ? await checkTicketNum(pieceOfData) : await postIDBCall(pieceOfData) }) Promise.all(result).then(x => { console.log(x) }) 

有一些意见:

  //fake data const data = [false, 10, 20, 30] //destructuring to avoid camunda.functionName const { checkTicketNum, postIDBCall } = require("./camunda") //map will return a table containing the result of your promises //Logging within a foreach does not garuantee you that the order of the logs is the execution order. Therefore, you can log at the end. const result = data.map(async(pieceOfData) => { //if(a){myVar=1} else if(!a){myVar=2} is not a good programing syntax. //Consider if(a){myVar=1} else {myVar=2}, //and even the ternary operator myVar = (a)?{1}:{2} //here : return (!pieceOfData) ? await checkTicketNum(pieceOfData) : await postIDBCall(pieceOfData) }) //finally lof the result. JSON.stringify will help with nested JSON Promise.all(result).then(x => { console.log(x) }) 

如果你想testing,这里是一个假camun.js文件:

 checkTicketNum = (x) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve("This is the checkTicketNum for " + x) }, 1000) }) } postIDBCall = (x) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(x + 1) }, 1000) }) } module.exports = { checkTicketNum, postIDBCall } 

编辑:那么,为了确保@Bergi告诉我什么,我写了一个完整的假库,所以这里是一个工作的例子。 我也对性能问题感到好奇,所以我testing了执行时间与asynchronous/等待或承诺完全相同。

 //CAMUN.JS checkTicketNum = (x) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve("This is the checkTicketNum for " + x) }, 1000) }) } postIDBCall = (x) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(x + 1) }, 1000) }) } //module.exports = { // checkTicketNum, // postIDBCall} //--------------------------// //MAIN FILE //destructuring to avoid camunda.functionName //const { checkTicketNum, postIDBCall } = require("./camunda") //fake data const data = [false, 10, 20, 30] console.time("await") const resultAwait = data.map(async(pieceOfData) => { return (!pieceOfData) ? await checkTicketNum(pieceOfData) : await postIDBCall(pieceOfData) }) Promise.all(resultAwait).then(x => { console.timeEnd("await") console.log("Await result : " + JSON.stringify(x)) }) console.time("promiseAll") const resultPromises = [] data.map((pieceOfData) => { return (!pieceOfData) ? resultPromises.push(checkTicketNum(pieceOfData)) : resultPromises.push(postIDBCall(pieceOfData)) }) Promise.all(resultPromises).then(x => { console.timeEnd("promiseAll") console.log("Promise result : " + JSON.stringify(x)) }) 

这就是我喜欢在循环中使用promise的方式

 let data = [10,20,30]; let promises = []; data.forEach(function (eachData) { let promise = new Promise((resolve,reject) => { setTimeout(function () { let newData = eachData + 10; resolve(newData) }, 1000) }); promises.push(promise); }); Promise.all(promises).then((data) => { console.log(data) //returns [20,30,40] }); 

基本上发生的是对于你在一个循环中运行的每一个承诺,你将这个承诺推送到一个数组中,并在Promise.all()的参数内部注入Promise.all()数组。 它可以被用来作为自我承诺,所以.then()函数是可能的。 数据以注入到promise数组中的顺序返回,不按resolve()