2017-09-05 54 views
1

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

以下代码当我有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); 
         }); 
        } 
    }); 
+1

看一看['Promise.all()'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) –

+0

您应该创建一个承诺数组,然后使用Promise.all()并在那里插入您的承诺数组。 –

+0

请注意,promise.all将并行处理所有内容,具体取决于您的承诺正在做什么,这可能会导致问题。蓝鸟有一个值得一看的并发选项的地图。另外一个简单的for循环与asyn/await混合也是一个想法。 – Keith

回答

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告诉我什么,我写了一个完整的假库,所以这里是一个工作示例。我也对性能问题感到好奇,所以我测试了执行时间与异步/等待或承诺完全相同。

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

+0

我想你忘了'await Promise.all'的某处? – Bergi

+0

**等待**的要点是表中充满了承诺的结果,而不是承诺本身。一旦承诺返回,表格将被填充。 ** await **的想法是允许您在Javascript中伪造同步代码。 –

+0

嗯,没有。结果表中充满了代码中的承诺。 – Bergi

0

这是我怎么样在一个循环中使用承诺

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()的参数内部注入promises数组。它可以被用来作为自我承诺,所以.then()函数是可能的。数据按顺序返回到promises数组中,顺序不是resolve()

+2

你应该使用'map'而不是'[]'+'forEach' +'push' – Bergi

+0

@Bergi你可以但为什么要这样? – forJ

+0

更简单 - 更安全 - 更短 - 更具可读性 - 更快 - 我可以继续... – Bergi

相关问题