Ben*_*rth 17 javascript promise
Promise.any()和之间有什么区别Promise.race(),它们的用法有何不同?
来自MDN,
此外,与返回第一个已解决值的 Promise.race() 不同,此方法返回第一个已解析值。此方法将忽略所有被拒绝的承诺,直到第一个解决的承诺。
所以这让我想到了resolve和stable之间的区别。然后将我带到 MDN 承诺页面,然后将我带到状态和命运
定居不是一种状态,只是一种语言上的便利。
所以我们有Promise.any和Promise.race为了语言方便?即没有区别。这种平等的另一个例子是“命运未决的承诺必然是未决的”。和“如果一个承诺不是待定的,即如果它被实现或被拒绝,我们说它被解决了。”。
所以如果一个 promise 被解决了,它就不是未解决的,所以它不是挂起的。那么,如果它不是待定的,它就已经解决了。所以解决了===解决了。
T.J*_*der 42
Promise.race并Promise.any做不同的事情:
Promise.race 一旦您提供给它的任何承诺解决,就会立即解决,无论它们是被实现还是被拒绝。
Promise.any是只要你的任何给它的承诺入驻满足或他们都拒绝了,在这种情况下,它拒绝用AggregateError。
主要区别是:
race当你给它的第一个承诺被拒绝时,它的承诺被拒绝;any不会,因为另一个承诺可能会被履行。
any的承诺的拒绝原因将是一个AggregateError,但race拒绝原因将是被拒绝的承诺的拒绝原因。
因此,如果您向它们传递两个 Promise 的数组,并且其中一个被拒绝,然后另一个承诺被履行,则承诺 fromPromise.race将被拒绝(因为第一个要解决的承诺被拒绝)并且承诺 fromPromise.any将被拒绝实现了(因为虽然第一个 promise 被拒绝了,但第二个 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()}`);
}
);Run Code Online (Sandbox Code Playgroud)
使用具有Promise.any(或 polyfill)的 JavaScript 引擎,输出
种族:被拒绝 任何:满足b
在这里玩各种结果(如果您的浏览器还没有包含,则包含一个非常粗略的不完整替代品Promise.any):
race: rejected with a any: fulfilled with b
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
});
}
}Run Code Online (Sandbox Code Playgroud)
提案中的这张图表可能会有所帮助:
+????????????????????????+?????????????????????????????? ?????????????????????+?????????????????????+ | 姓名 | 说明 | | +????????????????????????+?????????????????????????????? ?????????????????????+?????????????????????+ | Promise.allSettled | 不短路| 在 ES2020 中添加 | | Promise.all | 拒绝输入值时的短路| 在 ES2015 中添加 | | Promise.race | 输入值稳定时短路 | 在 ES2015 中添加 | | Promise.any | 满足输入值时短路 | 这个提议| +????????????????????????+?????????????????????????????? ?????????????????????+?????????????????????+
继续你的问题...
这种平等的另一个例子是“命运未决的承诺必然是未决的”。和“如果一个承诺不是待定的,即如果它被履行或被拒绝,我们说它被解决了。”。
所以如果一个 promise 被解决了,它就不是未解决的,所以它不是挂起的。那么,如果它不是待定的,则它已解决。所以解决了===解决了。
我可以看到你是如何到达那里的,但你不能那样颠倒它。:-) 一个已解决的承诺可能是挂起的。只是一个未解决的承诺肯定是悬而未决的。
这些州是:
您可以将一个 promise ( A)解析为另一个 promise ( B),这意味着虽然A可能仍处于挂起状态,但没有什么可以改变它将发生的事情;它的命运是封闭的,它会根据发生的事情来实现或拒绝B。
以下是未决已解决承诺的示例:
<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">Run Code Online (Sandbox Code Playgroud)