2017-02-22 113 views
0

從循環內嵌套承諾返回承諾的最佳方式是什麼?我不確定如何使用何時或如何擺脫嵌套承諾。Jquery在ForEach循環內嵌套承諾

function UploadDocuments() 
{ 

_.forEach(documentArray, function (document) { 

      uploadHelper.uploadFile(document.file, "Doclib").done(function (results) { 

       //success 
       uploadHelper.getDocumentListItem(results.d.ListItemAllFields.__deferred.uri).done(function (listItem) { 

        var payLoad = { 
         "Title": document.title, 
         "FileLeafRef": document.title, 
        }; 

        //success 
        uploadHelper.updateDocumentListItem(listItem.d.__metadata, payLoad).done(function() { 
         alert("Successfully Uploaded Document"); 

        }).fail(function() { 

         alert("Upload failed"); 
        }); 

       }).fail(function() { 

        alert("get listItem failed"); 
       }); 

      }).fail(function() { 

       alert("upload failed"); 
      }); 

     }); 

} 

我希望能夠調用此函數返回一個承諾,然後繼續處理。之後如

UploadDocuments().then(function(){ 
     //continue 

});

回答

0

我不確定是否有一種很好的方式,或者至少我不能想到一個,做你正在做的循環。一個promise只能解析一次,所以它必須在循環完成後運行,但假設你的uploadHelper對象大部分是異步方法,那麼不能保證這些異步操作在循環結束時會通過/失敗,並且promise會解析。

看起來好像更好的模式可能是Promise.all(),它接受承諾中包裝的異步操作數組,並在所有這些操作都通過時解析。這將需要對輔助方法進行一些修改,但是您可以遍歷文檔並添加一個承諾,讓所有人都可以將文檔處理到數組中,然後在結果數組上調用Promise.all()。

+0

是的,我有點難住,uploadhelper返回.ajax諾言,它只是調用一個休息API(SharePoint 2013)。我正在上傳每個文件,然後獲取每個文檔listitem,然後更新每個listitem。如果鏈條的一部分失效,不確定鏈接或處理錯誤的最佳方式。 – Fab

+0

是的,那是Promise.all()的缺點。如果一個承諾被拒絕,那麼整個事情都會被拒絕。承諾的大部分用途是在獲得返回數據後確定操作,但似乎並沒有從上次調用中返回任何內容?有些東西沒有工作,或者你只是在尋找更好的模式? –

+0

只是尋找一個更好的模式,並希望繼續如果一個文件上傳失敗,但我想這將因爲我有呼叫之外的循環 – Fab