簡體   English   中英

承諾鏈在最后一個承諾解決之前就解決了

[英]promise chain resolves before its last promise resolves

背景
從2個幾乎完全相同的javascript開始,然后重構為3:一個實用程序腳本,其中包含以前的冗余代碼+ 2個調用腳本。

問題
這兩個原始腳本使用了jQuery Deferreds(when.then),並且運行良好。 3腳本方案失敗,因為倒數第二個諾言會從一個調用腳本中盡早解決

細節
第一個腳本稱為“ multi”,它使用一系列遞延操作來循環一系列ajax請求,然后在瀏覽器中刷新“ multi”頁面。 所以:

auth -> user -> loop (updateIssue -> transition) end loop -> refresh

第二個“單個”有效地使用相同的代碼而不循環,然后使用不同的refresh功能

我的目的是將代碼重構為實用程序腳本中的promise鏈,並使用如下代碼:

// calling script
Utility.promiseChain().done(refresh())

// utility script
Utility.promiseChain = function() {
return authPromise()
.then(function() { return userPromise();} )
.then(function() { return Promise.all(array of update.then(transition) promises);})} 

問題,更具體地說
Promise.all調用始終在update后但在transition之前解析,從而導致refresh提前觸發,然后進行transition 您可以提供的任何見解將最有幫助。

Promise.all調用始終在更新之后但在過渡之前解決

唯一可能發生的方法是,如果事件鏈中的某些內容未正確鏈接諾言。 您必須向我們展示真實的代碼,以幫助您識別特定的問題,但是,如果Promise.all()沒有等待transition承諾,則該承諾不能正確地鏈接到Promise.all()的承諾數組中Promise.all()正在等待。

具體來說,我們需要查看偽代碼這一部分背后的代碼:

array of update.then(transition) promises

確切地了解transition()是如何創建該諾言數組的。 與往常一樣,如果您向我們展示您的REAL代碼而不只是偽代碼,我們可以幫助您找到編程邏輯中實際錯誤的根源。

一種可能的情況是,您正在使用JQuery <版本3,並且對authPromise()的調用將返回JQuery authPromise() 這意味着Utility.promiseChain返回的promise鏈中then返回的所有promise都是JQuery Promise。 我上次檢查時,較早版本的JQuery不能將外部庫的承諾(包括由本地Promise構造函數返回的承諾)識別為承諾,並且可以實現用一個人解決的JQuery承諾,而無需等待其解決。

Promise.all返回的Promise.all對象可能

.then(function() { return Promise.all( // ...

被用來履行返回的承諾, then無需等待它解決。

簡而言之,您無法使用ES6 Promise解析舊版本的JQuery Promise,而無法產生通過Promise解決Promise的效果。

潛在的解決方案:

  1. 升級到JQuery 3(您失去了對IE的舊版本的支持,但無論如何它們都不支持Promise )。 推薦(如果可以的話)。

  2. 通過調用Promise.resolve( jqPromise)將所有promise用法轉換為ES6樣式promise,並將使用前傳遞給Promise.resolve( jqPromise)所有JQuery promise轉換為

  3. 反向編寫與Promise.resolve等效的Promise.resolve ,以將ES6承諾轉換為JQuery承諾。 我會盡可能地給它打分,但是會向錯誤的方向倒退。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM