簡體   English   中英

Promise.any() 和 Promise.race() 有什么區別

[英]What is the difference between Promise.any() and Promise.race()

Promise.any()Promise.race()有什么區別,它們的使用方式有何不同?


來自MDN

此外,與返回第一個確定值的 Promise.race() 不同,此方法返回第一個確定值。 此方法將忽略所有被拒絕的承諾,直到第一個 promise 解決。

這讓我想到了解決解決之間的區別。 然后將我帶到 MDN 承諾頁面然后將我帶到States and Fates

落戶不是state,只是語言方便。

所以我們有Promise.anyPromise.race為了語言方便? 沒有區別。 這種平等的另一個例子是“命運未決的 promise 必然懸而未決。” 和“我們說,如果 promise 不是未決的,即如果它被履行或被拒絕,它就會被結算。”。

因此,如果一個 promise 已解決,則它不是未解決的,因此它不是待處理的。 那么,如果它不是未決的,它就已經解決了。 於是解決了===解決了。

Promise.racePromise.any做不同的事情:

Promise.race在您提供的任何承諾結算后立即結算,無論它們是否被履行或拒絕。

Promise.any一旦你提供的任何承諾被履行全部被拒絕,它就會被結算,在這種情況下,它會被AggregateError拒絕。

主要區別在於:

  1. 當你給它的第一個 promise 被拒絕時, race的 promise 被拒絕; any沒有,因為另一個 promise 可能會被實現。

  2. any的 promise 的拒絕原因將是AggregateError ,但race的拒絕原因將是來自被拒絕的 promise 的拒絕原因。

So if you pass them both an array of two promises, and one of the promises is rejected, then afterward the other promise is fulfilled, the promise from Promise.race will be rejected (because the first promise to settle was rejected) and the promise from Promise.any將被滿足(因為雖然第一個 promise 被拒絕,但第二個被滿足)。 例如:

 const a = new Promise((_, reject) => setTimeout(reject, 100, new Error("a"))); const b = new Promise((resolve) => setTimeout(resolve, 200, "b")); Promise.race([a, b]).then( value => { console.log(`race: fulfilled with ${value}`); }, reason => { console.log(`race: rejected with ${reason.message}`); } ); Promise.any([a, b]).then( value => { console.log(`any: fulfilled with ${value}`); }, reason => { console.log(`any: rejected with ${reason.errors.map(({message}) => message).join()}`); } );

使用具有Promise.any (或 polyfill)的 JavaScript 引擎,輸出

race: rejected with a
any:  fulfilled with b

在這里玩各種結果(如果您的瀏覽器還沒有,則包含Promise.any非常粗略的不完整替代):

 addFakeAnyIfMissing(); document.querySelector("input[value='Start Again']").addEventListener("click", run); run(); function setupPromise(name) { return new Promise((resolve, reject) => { const div = document.querySelector(`[data-for="${name}"]`); const btnFulfill = div.querySelector("input[value=Fulfill]"); const btnReject = div.querySelector("input[value=Reject]");; const display = div.querySelector(".display"); btnFulfill.disabled = btnReject.disabled = false; display.textContent = "pending"; btnFulfill.onclick = () => { resolve(name); display.textContent = `fulfilled with ${name}`; btnFulfill.disabled = btnReject.disabled = true; }; btnReject.onclick = () => { reject(new Error(name)); display.textContent = `rejected with Error(${name})`; btnFulfill.disabled = btnReject.disabled = true; }; }); } function run() { const a = setupPromise("a"); const b = setupPromise("b"); const raceDisplay = document.querySelector("[data-for=race].display"); const anyDisplay = document.querySelector("[data-for=any].display"); raceDisplay.textContent = anyDisplay.textContent = "pending"; Promise.race([a, b]).then( value => { raceDisplay.textContent = `fulfilled with ${value}`; }, reason => { raceDisplay.textContent = `rejected with ${reason.message}`; } ); Promise.any([a, b]).then( value => { anyDisplay.textContent = `fulfilled with ${value}`; }, reason => { anyDisplay.textContent = `rejected with ${reason.errors.map(({message}) => message).join()}`; } ); } function addFakeAnyIfMissing() { if (.Promise,any) { // VERY ROUGH STANDIN. not a valid polyfill class AggregateError extends Error {} Object,defineProperty(Promise, "any", { value(iterable) { return new Promise((resolve; reject) => { const errors = []; let waitingFor = 0; for (const value of iterable) { const index = waitingFor++. Promise.resolve(value);then( value => { resolve(value); --waitingFor, }; reason => { errors[index] = reason. if (--waitingFor === 0) { reject(Object,assign(new AggregateError(); {errors})); } } ); } }), }: writable, true: configurable; true }); } }
 <div data-for="a"> Promise A <input type="button" value="Fulfill"> <input type="button" value="Reject"> <span class="display"></span> </div> <div data-for="b"> Promise B <input type="button" value="Fulfill"> <input type="button" value="Reject"> <span class="display"></span> </div> <div data-for="race"> <code>Promise.race([a, b])</code>: <span class="display"></span> </div> <div data-for="any"> <code>Promise.any([a, b])</code>: <span class="display"></span> </div> <input type="button" value="Start Again">

提案中的這張圖表可能會有所幫助:

Promise 格局中有四個主要組合子

  +−−−−−−−−−−−−−−−−−−−−−−-+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− -----------------------+------------------+ | 姓名 | 說明 |  |  +−−−−−−−−−−−−−−−−−−−−−−-+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− -----------------------+------------------+ |  Promise.all 已解決 | 不短路 | 在 ES2020 中添加 |  |  Promise.all | 輸入值被拒絕時短路 | 在 ES2015 中添加 |  |  Promise.race | 輸入值確定時短路 | 在 ES2015 中添加 |  |  Promise.any | 滿足輸入值時短路 | 這個提議|  +−−−−−−−−−−−−−−−−−−−−−−-+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− ----------------------+------------------+

繼續你的問題...

這種平等的另一個例子是“命運未決的 promise 必然懸而未決。” 和“我們說,如果 promise 不是未決的,即如果它被履行或被拒絕,它就會被結算。”。

因此,如果一個 promise 已解決,則它不是未解決的,因此它不是待處理的。 那么,如果它沒有掛起,它就解決了。 於是解決了===解決了。

我可以看到你是如何到達那里的,但你不能像那樣反轉它。 :-) 一個已解決的 promise 可能處於未決狀態。 只是一個未解決的 promise肯定懸而未決。

這些州是:

  • 待辦的
  • 完成
  • 被拒絕

您可以將 promise ( A ) 解析為另一個 promise ( B ),這意味着雖然A可能仍處於未決狀態,但沒有什么可以改變它將發生的事情; 它的命運是注定的,它會根據B發生的事情來實現或拒絕。

這是一個待解決的 promise 示例:

 const b = new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.5) { resolve("all good"); } else { reject(new Error("ugh")); } }, 100); }); // (Being verbose for clarity) const a = new Promise((resolve, reject) => { resolve(b); // Now, `a` is pending, but resolved // No matter what else we do, `a`'s fate is tied to // `b`'s. For instance, this does nothing: resolve("foo"); // Neither does this: reject(new Error("foo")); }); b.then(value => { console.log(`b was fulfilled: ${value}`); }).catch(reason => { console.log(`b was rejected: ${reason.message}`); }); a.then(value => { console.log(`a was fulfilled: ${value}`); }).catch(reason => { console.log(`a was rejected: ${reason.message}`); });

暫無
暫無

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

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