簡體   English   中英

掙扎於 Promise.race() 實現

[英]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的resolvereject參數重復調用時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);

因此,通過循環並將相同的resolvereject附加到所有 promise, race只會以與第一個 promise 相同的結果來解決。 這與Promise.race()的 JavaScript 實現相匹配:

返回值

一個 Promise 與iterable中第一個 promise 的最終 state異步結算以結算。 換句話說,如果第一個結算的promise被履行,它就履行;如果第一個結算的promise被拒絕,它就拒絕。 如果傳遞的iterable為空,則返回的 promise 將永遠掛起。 如果傳遞的iterable對象非空但不包含未決承諾,則返回的 promise 仍然是異步(而不是同步)結算的。

NB iterablePromise.race()的輸入。 它匹配race()promisesArray


盡管如此,以下構造似乎完全是多余的:

p
  .then(resolve, reject) 
  .catch(reject);

.then .then()的第二個參數是 onRejected 回調 因此,如果p被拒絕, .then()的第二個參數將用於處理它。 額外的.catch()將處理來自 .then( .then()resolvereject的錯誤

 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 的resolvereject都不能在普通的 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.

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