[英]Struggling with Promise.race() implementation
我看到了以下 Promise.race() 的實現。
我發現很難理解它是如何工作的。
const race = function(promisesArray) {
return new Promise((resolve, reject) => {
promisesArray.forEach((innerPromise) => {
Promise.resolve(innerPromise)
.then(resolve, reject)
.catch(reject);
});
});
};
第一部分:以下說法正確嗎?
Promise.resolve(innerPromise) 將始終以 innerPromise 為值返回已解決的 promise 並且因為它總是解決,所以我將始終以 in.then 塊結束。
第二部分:
我在解釋中讀到 resolve 和 reject passed to.then 塊將在 innerPromise 的解析中被調用。 為什么?,不應該像 Promise.resolve(innerPromise) 總是解決,總是第一個回調 of.then 塊應該被調用?
我想我缺少一些非常基本的東西。 我試圖找到解決方案,但無法找到消除我疑慮的解釋。
該代碼中Promise.resolve
的目的是允許數組的元素不是承諾。 它們可以是任意的 thenables,或者它們可以只是常規值(它們確實會成為已實現的承諾)。
const existingValue = 5; const existingPromise = Promise.reject(new Error("blah")); const existingThenable = { then() { console.log("never going to resolve >:)"); } }; Promise.race([existingValue, existingPromise, existingThenable]).then( value => { console.log("got a value", value); }, error => { console.log("got an error", error); }, );
第一部分:以下說法正確嗎?
Promise.resolve(innerPromise) 將始終以 innerPromise 為值返回已解決的 promise 並且因為它總是解決,所以我將始終以 in.then 塊結束。
如果您嘗試從上面傳遞給Promise.race
的數組中刪除existingValue
,您會看到Promise.resolve
不一定返回已解析的 promise; 具體來說,當它通過 promise 或其他可用時,它返回一個 promise 以相同的方式結算(盡管當通過相同類型的 promise 時,它實際上通過返回相同的 promise 對象來滿足該義務)。 所以不,這不是真的。 我認為這也回答了第 2 部分。
此外,盡管您沒有提出來:我很確定額外的.catch(reject)
是無法訪問/無用的,至少對於標准 ES Promise
實現而言是這樣。
Promise.resolve(anotherPromise)
將始終假定 anotherPromise 的anotherPromise
,因此如果anotherPromise
被拒絕,那么來自Promise.resolve()
的那個也將被拒絕。 或者,如果anotherPromise
已實現,則Promise.resolve()
也將以其值實現。
const rejectedPromise = Promise.reject("boom"); Promise.resolve(rejectedPromise).then(result => console.log("success:", result)).catch(error => console.log("failure:", error));
請參閱有關Promise.resolve()
的 MDN 文檔。
至於為什么代碼是使用Promise.resolve()
而不是直接
innerPromise
.then(resolve, reject)
.catch(reject);
當輸入不一定是 promise 時, Promise.resolve()
很有用。它可以將普通值轉換為 promise 或任意 thenable(可能是另一個 promise 實現)轉換為香草 JavaScript promise,從而允許統一處理結果。
也許這是防御性編碼,或者只是允許調用race(asyncResult, 42)
。 意圖不明確。
into執行器function的resolve
或reject
參數重復調用時noop。 promise 可以達到單個最終 state - 之后調用resolve
/ reject
無效。 因此,從整個數組中,第一個 promise 離開未決的 state 將決定 promise 構造函數將被解析為什么。
const p1 = new Promise((resolve, reject) => { Promise.resolve("p1 success").then(resolve, reject).catch(reject); Promise.reject("p1 failure").then(resolve, reject).catch(reject); }); const p2 = new Promise((resolve, reject) => { Promise.reject("p2 failure").then(resolve, reject).catch(reject); Promise.resolve("p2 success").then(resolve, reject).catch(reject); }); const p3 = new Promise((resolve, reject) => { Promise.resolve("p3 hello").then(resolve, reject).catch(reject); Promise.resolve("p3 world").then(resolve, reject).catch(reject); }); const p4 = new Promise((resolve, reject) => { Promise.reject("p4 foo").then(resolve, reject).catch(reject); Promise.reject("p4 bar").then(resolve, reject).catch(reject); }); p1.then(console.log, console.error); p2.then(console.log, console.error); p3.then(console.log, console.error); p4.then(console.log, console.error);
因此,通過循環並將相同的resolve
和reject
附加到所有 promise, race
只會以與第一個 promise 相同的結果來解決。 這與Promise.race()
的 JavaScript 實現相匹配:
返回值
一個 Promise 與
iterable
中第一個 promise 的最終 state異步結算以結算。 換句話說,如果第一個結算的promise被履行,它就履行;如果第一個結算的promise被拒絕,它就拒絕。 如果傳遞的iterable
為空,則返回的 promise 將永遠掛起。 如果傳遞的iterable
對象非空但不包含未決承諾,則返回的 promise 仍然是異步(而不是同步)結算的。
NB iterable
是Promise.race()
的輸入。 它匹配race()
的promisesArray
。
盡管如此,以下構造似乎完全是多余的:
p
.then(resolve, reject)
.catch(reject);
.then .then()
的第二個參數是 onRejected 回調。 因此,如果p
被拒絕, .then()
的第二個參數將用於處理它。 額外的.catch()
將處理來自 .then( .then()
中resolve
或reject
的錯誤
Promise.resolve("foo").then( result => { throw `Fulfilled with ${result}. Throwing after success.` }, error => {throw `Fulfilled with ${error}. Throwing after error` } ).catch(errorFromThen => console.log(`Error in.catch() is: ${errorFromThen}`)); Promise.reject("bar").then( result => { throw `Fulfilled with ${result}. Throwing after success.` }, error => {throw `Fulfilled with ${error}. Throwing after error` } ).catch(errorFromThen => console.log(`Error in.catch() is: ${errorFromThen}`));
然而,執行者 function 的resolve
和reject
都不能在普通的 Promise 構造函數中拋出/拒絕。
//more verbose onError and.catch() handlers in order to showcase what gts shown or not const p = new Promise((resolve, reject) => { Promise.reject("hello").then( resolve, error => { console.log("inside the onReject in.then()", error); return reject(error); }).catch(error => { console.log("inside the.catch()", error); return reject(error); }); Promise.reject("world").then( resolve, error => { console.log("inside the onReject in.then()", error); return reject(error); } ).catch(error => { console.log("inside the.catch()", error); return reject(error); }); }); p.then(console.log, console.error);
因此不使用額外的.catch()
。
總體而言, race()
的行為類似於 vanilla JavaScript Promise.race()
。 唯一的主要區別是Promise.race()
接受任何可迭代對象,而race()
僅處理 arrays。
const delay = (ms, value) => new Promise(resolve => setTimeout(resolve, ms, value)); const array = [delay(300, "a"), delay(100, "b"), delay(200, "c")]; const iterable = array.values(); Promise.race(iterable).then(result => console.log(`First to fulfil was ${result}`));
const race = function(promisesArray) { return new Promise((resolve, reject) => { promisesArray.forEach((innerPromise) => { Promise.resolve(innerPromise).then(resolve, reject).catch(reject); }); }); }; const delay = (ms, value) => new Promise(resolve => setTimeout(resolve, ms, value)); const array = [delay(300, "a"), delay(100, "b"), delay(200, "c")]; const iterable = array.values(); race(iterable).then(result => console.log(`First to fulfil was ${result}`)).catch(console.error);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.