2016-03-08 62 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