What is the difference between Promise.any() and Promise.race()
从MDN,
Also, unlike Promise.race(), which returns the first settled value,
this method returns the first resolved value. This method will ignore
all rejected promises up until the first promise that resolves.
这样就使我明白了解决与解决之间的区别。 然后将我带到MDN承诺页面,然后将我带到各州和命运
Being settled is not a state, just a linguistic convenience.
那么为了语言方便,我们有
因此,如果一个诺言得以解决,那么它就不会成为未解决的,因此它不会待定。 因此,如果它没有待处理,则解决。 如此解决===解决了。
主要区别在于:
当您给出的第一个承诺被拒绝时,
因此,如果您同时向它们传递两个承诺的数组,并且其中一个承诺被拒绝,然后又满足另一个承诺,则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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()}`); } ); |
使用具有
1 2 | race: rejected with a any: fulfilled with b |
在这里发挥多种效果(如果您的浏览器尚不具备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 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 }); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Promise A <input type="button" value="Fulfill"> <input type="button" value="Reject"> <span class="display"></span> Promise B <input type="button" value="Fulfill"> <input type="button" value="Reject"> <span class="display"></span> <wyn>Promise.race([a, b])</wyn>: <span class="display"></span> <wyn>Promise.any([a, b])</wyn>: <span class="display"></span> <input type="button" value="Start Again"> |
提案中的以下图表可能会有所帮助:
There are four main combinators in the Promise landscape.
1
2
3
4
5
6
7
8 +????????????????????+?????????????????????????????????????????????????+?????????????????+
| name | description | |
+????????????????????+?????????????????????????????????????????????????+?????????????????+
| Promise.allSettled | does not short-circuit | Added in ES2020 |
| Promise.all | short-circuits when an input value is rejected | Added in ES2015 |
| Promise.race | short-circuits when an input value is settled | Added in ES2015 |
| Promise.any | short-circuits when an input value is fulfilled | this proposal |
+????????????????????+?????????????????????????????????????????????????+?????????????????+
继续您的问题...
Another instance of this equality, is"A promise whose fate is unresolved is necessarily pending." and"We say that a promise is settled if it is not pending, i.e. if it is either fulfilled or rejected.".
So if a promise is resolved, it is not unresolved, so it is not pending. So then, if its not pending, its settled. So resolved === settled.
我可以看到您是如何到达那里的,但是您无法像那样将其反转。 :-)已解决的承诺可能尚未落实。只是一个未解决的承诺肯定是未决的。
状态为:
- 待定
- 完成
- 拒绝
您可以将一个诺言(
这是一个未决的已解决承诺的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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}`); }); |