我有事件流向程序下方,因此基于事件值我会触发不同的承诺,所以我想检查在forEach中使用promises的好主意。
如果我在事件中有 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
};
值,则使用以下代码,它永远不会满足条件。知道什么是错误的我对承诺是相当新的。以下代码的任何示例高度赞赏。
camunda.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);
});
}
});
promise.js
api: cd apps/api && mix phx.server
clientside: cd apps/clientside && mix phx.server
答案 0 :(得分:2)
编辑:感谢@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) })
如果你想测试,这是一个假的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告诉我的内容,我写了一个完整的假库,所以这是一个有效的例子。我也对性能问题感到好奇,所以我测试了async / await或promises的执行时间完全相同。
//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))
})
答案 1 :(得分:0)
这就是我喜欢在循环中使用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,将该promise转换为数组,并在Promise.all()
的参数内注入promises
数组。然后它可以用作自己的承诺,因此.then()
功能是可能的。数据以注入到promises数组的顺序返回,而不是按resolve()