2017-03-01 142 views
0

下面,您會看到我在註釋代碼中遇到問題的位置。我有一個嵌套承諾,在集合中創建一個對象,然後返回它。無法獲得嵌套承諾以將值返回到下一個承諾鏈

但是,我想我有一個與異步問題。該函數在嵌套promise返回創建的對象之前完成。

我仍在抓住承諾鏈接,我可能在這裏犯了很多錯誤。如果我可以清理/弄平這些,這些可能會被清除。

PostSchema.statics.createPost = function (o, user) { 
    var whiskey; 
    return Whiskey 
     .createWhiskey(o.whiskey.value) 
     .then(function (whiskeyData) { 
      whiskey = whiskeyData.whiskey; 
      o.post.whiskey = whiskeyData.whiskey._id; 

      if (whiskeyData.whiskey.distiller) { 
       o.post.distiller = whiskeyData.whiskey.distiller; 
      } 

      return o.distiller.new === true && !whiskey.distiller ? Distiller.newDistiller(o.distiller.value) : Promise.resolve() 
       .then(function (distiller) { 
        //this never invokes <---- it's called from the function below 
        console.log('never invokes', distiller). 
        if (distiller) { 
         whiskey.distiller = distiller._id; 
         //test this save 
         whiskey.save(); 
         o.post.distiller = distiller._id; 
        } 

        var post = o.post; 
        post.user = user._id; 
        return Post 
         .createAsync(post) 
         .then(function (data) { 
          return Post 
           .populate(data, { 
            path: 'user whiskey', 
            populate: { 
             path: 'distiller style', 
            } 
           }) 
         }) 

         .then(function (populatedData) { 
          return (user.shareFB ? social.checkFB(user, populatedData) : Promise.resolve()) 
           .then(function (FBres) { 
            return (user.shareTWT ? social.checkTWT(user, populatedData) : Promise.resolve()) 
             .then(function (TWTres) { 
              var socialData = [TWTres, FBres]; 
              return { 
               'post': populatedData, 
               'social': socialData 
              }; 
             }) 
           }) 
         }) 
       }) 
     }) 
     .catch(function (err) { 
      console.log('post create err : ', err); 
     }) 
}; 

這是創建在蒸餾並試圖返回:

DistillerSchema.statics.newDistiller = function (o) { 

    return Distiller 
     .findAsync({ 
      'name': o.name 
     }) 
     .then(function (distiller) { 
      if (distiller.length) { 
       return distiller[0]; 
      } 
      return Distiller 
      .createAsync(o) 
      .then(function (data) { 
       //console.log here indicates that is is created <-- created and returned here 
       console.log('distiller created ', data) 
       return data; 
      }) 
     }) 
     .catch(function(err) { 
      console.log('create distiller err ', err); 
     }) 
}; 
+1

如果你的代碼嵌套9層深,那麼你已經可以斷定你沒有正確使用承諾。不要築巢。鏈。 – trincot

+0

Promise.resolve()將undefined傳遞給鏈中的下一個函數。 '函數(whiskeyData)威士忌=威士忌數據。威士忌;如果威士忌數據是未定義的,將會中斷,會跳到趕上 – lonewarrior556

+0

是的,我應該刪除那個三元。威士忌是必需的領域。 – NoobSter

回答

1

聽起來像一個分組的錯誤。取而代之的

return o.distiller.new === true && !whiskey.distiller 
    ? Distiller.newDistiller(o.distiller.value) 
    : Promise.resolve().then(…) // callback only called when no new distiller 

你想

return (o.distiller.new && !whiskey.distiller 
    ? Distiller.newDistiller(o.distiller.value) 
    : Promise.resolve() 
).then(…) // callback always called 

至少,這是如何做到的所有其他條件語句:-)

我還在抓承諾鏈接

在得知您總是需要來自異步功能的return之後(你做得很好),你應該看看how it is possible to flatten a chain(當所有的條件只是局部表達式時,它適用於你的代碼,而不是早期返回)。另外,我建議不要縮進鏈式方法調用,因爲在嵌套then回調時,這會很快失控,但這只是我個人的偏好。

+0

謝謝@Bergi。不能相信我錯過了這一點。感謝承諾指導! – NoobSter