如何在forEach中调用promise?

时间:2017-09-05 19:36:49

标签: javascript node.js promise

我有事件流向程序下方,因此基于事件值我会触发不同的承诺,所以我想检查在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

2 个答案:

答案 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()

的顺序