如果 Promise p
使用 Promise(或 Thenable)q
的值解析,它本质上成为 Promise q
的副本。如果 q
被解析,p
将被解析为相同的值。
Promise.resolve(Promise.resolve("hello"));
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "hello"}
如果 q
被拒绝,p
将被拒绝并具有相同的值。
Promise.resolve(Promise.reject(new Error("goodbye")));
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: Error: goodbye}
Promise p
是通过 Promise q
解决/拒绝的,而不是直接使用各自的值,这一事实与最终结果无关。中间 Promise 作为解析过程的一部分被消费,并且对消费者不可见。
如果 q
永远不会被解决或拒绝,p
也将永远保持未决状态。
Promise.resolve(new Promise(() => null)); // perpetually-pending promise
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
这些案例是众所周知的,但我从未见过如果一个 Promise 被另一个 Promise 值拒绝(而不是解决)会发生什么。拒绝过程是否也消耗中间 Promise,还是它们原封不动地通过?
如果它确实消耗了它们,它是如何工作的?
最佳答案
让我们看看如果我们用已解决的 Promise q
拒绝 Promise p
会发生什么:
Promise.reject(Promise.resolve("hello"));
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: Promise}
Uncaught (in promise) Promise {
[[PromiseStatus]]: "resolved", [[PromiseValue]]: "hello"}
或者更明确地说:
const q = Promise.resolve("hello");
const p = Promise.reject(q);
p.then(null, x => console.log("Rejection value:", x));
Rejection value: Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "hello"}
Promise q
,拒绝值,永远不会展开! p
的拒绝处理程序使用 Promise 调用q
本身,而不是它包含的值。
这也意味着 p
的拒绝处理程序不需要等待 q
被解析后才能运行。即使 q
永远不会被解析,p
的拒绝处理程序仍然可以被调用。
Promise.reject(new Promise(() => null)); // Reject with perpetually-pending Promise
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: Promise}
Uncaught (in promise) Promise {
[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
最后,让我们确认一下如果我们使用另一个被拒绝的 Promise q
来拒绝 Promise p
的行为:
Promise.reject(Promise.reject(new Error("goodbye")));
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: Promise}
Uncaught (in promise) Error: goodbye(…)(anonymous function)
Uncaught (in promise) Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: Error: goodbye}
我们再次看到 q
没有展开,p
的拒绝处理程序将使用 q
本身调用,而不是调用的值q
已被拒绝。
关于javascript - 如果我拒绝具有另一个 Promise 值的 Promise 会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39197769/