2016-03-08 67 views
0

我正在使用水线+帆为一个API,我有以下函数嵌套exec()调用。嵌套的异步JavaScript函数

AcademyService.getAll().exec(function (error, data) { 

     if (error) { 

      return res.json({result: false, message: error}); 

     } 

     var academies = data; 

     for (var i = 0; i < Object.keys(academies).length; i++) { 

      var user_id; 

      user_id = academies[i].academy_user_id; 

      (function (index) { 

       UserService.getOneById(user_id).exec(function (error, data) { 

        if (error) { 

         academies[index].academy_user_id = null; 

        } 

        academies[index].academy_user_id = data.user_fname+" "+data.user_lname; 

       }); 

      })(i); 

     } 

     return res.json({result: true, academies: academies}); 

    }); 

上面代码的问题是,最后一个return语句没有更新academies对象。即它的academy_user_id没有更新的值。我将其归因于调用的异步行为,我认为当我们达到最后一次返回时,UserService的异步调用仍在循环中运行,并且更新的academies对象未传递。

现在,草率的解决方案是将回调UserService.getOneById回调中的academies对象用循环结束检查返回,但这似乎不是正确的方法。那么,我们可以以某种方式同步执行内部exec()吗?

+0

一个很酷的解决办法是使用承诺:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise –

回答

1

风帆与async库捆绑在一起,非常适合这种情况。异步在sails中全局可用,因此您不需要它,甚至可以将它添加到您的依赖项中。使用async.each而不是for循环。

像这样的东西应该工作

AcademyService.getAll().exec(function(error, academies) { 
    if (error) { 
     return res.json({ 
      result: false, 
      message: error 
     }); 
    } 

    async.each(
     academies, 
     function (academy, cb) { 
      var user_id = academy.user_id; 

      UserService.getOneById(user_id).exec(function (err, user) { 
       if (err) { 
        academy.academy_user_id = null; 
       } 
       else { 
        academy.academy_user_id = user.user_fname + ' ' + user.user_lname; 
       } 

       return cb(); 
      }); 
     }, 
     function (err) { 
      if (err) { 
       return res.json({ 
        result: false, 
        message: err 
       }); 
      } 

      return res.json({ 
       result: true, 
       academies: academies 
      }); 
     } 
    ); 
}); 
+0

哇。我想知道你住在哪里:D只是我想要的解决方案。谢谢! – xmaestro