【问题标题】:how to convert a for loop callback into sync in node js (Express js)如何在节点 js(Express js)中将 for 循环回调转换为同步
【发布时间】:2018-10-01 05:18:42
【问题描述】:

我有一个集合 object_id 的数组,例如 [123, 426, 789] 我需要编写一个 for 循环来从集合中找到该对象到每个对象的某个操作,目前,我正在编码

let obj = ["5acf60d327cca60880b4a257", "5a9e3c642b6b04387208b24c", "5acf60ab27cca60880b4a252"];
for(let i =0; i<=obj.lenth;i++){
    if(i=== obj.length){
        return callback({
            code : 200,
            status: 'sucess',
            message: "Mail Requested Sucessfully"
        });
    }else{
        user.findbyId(obj[i]).exec((err, userData) => {
            if(err){
                console.log("user not found");
            }else{
                transporter.sendMail({
                    from: '"Fred Foo ????" <foo@example.com>', // sender address
                    to: userData.emailID, // list of receivers
                    subject: 'Hello ✔', // Subject line
                    html: '<b>Hello world?</b>' // html body
                }, (error, info) => {
                    if (error) {
                        onsole.log('Message sent: %s', error);
                    }
                    console.log('Message sent:', info);
                });
            }
        })
    }
} 

目前,它以异步方式工作,有什么好的方法可以使其以同步方式实现

【问题讨论】:

  • onsole.log('Message sent: %s', error); 应该是 console.log('Message sent: %s', error);(只是旁注)
  • 更好:保持您的请求异步,但有序。例如,不是一次启动所有请求,而是让第一个请求的结果回调触发第二个,等等。
  • 这是一个看起来很奇怪的代码 :) 您基本上是在循环对象并创建多个异步调用,并且在循环结束时(由 i === obj.length 触发)您正在调用回调... 为什么不在“标准”循环之后立即调用回调,直到

标签: javascript node.js mongodb express asynchronous


【解决方案1】:

是的,你可以。让你的回调返回一个承诺,然后你可以在 for 循环中 await 来解决这个问题,其余的循环代码将在回调解决后执行。

这是要走的路

(async function(){
 for(let i =0; i<=obj.lenth;i++){
   if(i=== obj.length){
      await callback1(params)
   }else{
      await callback2(params)
   }
})();

在一些承诺中定义你的user.findbyId(obj[i]).exec((err, userData)

有点像

function callback2(params){
    return new Promise((resolve,reject)=>{
      user.findbyId(obj[i]).exec((err, userData) => {
        if(err){
            resolve (error)
        }else{ /*send message and resolve promise*/
 })
}

【讨论】:

  • .exec() 已经返回 Promise: mongoosejs.com/docs/api.html#query_Query-exec
  • OP 在他的代码中实现可能更容易,但必须记住,效果类似于同步行为。只要请求未完成,javascript 引擎实际上就会卡在 for 循环中,并可能对用户与 UI 的交互产生副作用
猜你喜欢
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多