众所周知,可以将多个 Promise 组合成一条链,从而准确地一个接一个地调用 onFulfilled
回调(尽管它们将彼此异步):
Promise.resolve()
.then(() => {
console.log("i will be the first one");
})
.then(() => {
console.log("i will be the second one"); // definetely second
})
;
但是非链式后续 Promise 呢? 最简单的例子:
Promise.resolve()
.then(() => console.log("i will be the first one"))
;
Promise.resolve()
.then(() => console.log("i will be the second one")) // sure?
;
在我天真的观点中,Promises 回调通过事件队列工作(类似于 setTimeout
中的计时器事件),并且首先 Promise.resolve()
将其事件插入在第二个之前排队,因此第一个回调将在第二个之前调用。
但我不确定是否有任何保证。我可以依靠它还是异步乐透?有人知道它的规范说明吗?
更新
你们中的一些人注意到最简单的例子是无用的,所以我想解释一下我原来的问题。
我有一个类,它延迟初始化另一个类的实例并为托管实例提供 get 方法:
class Lazy {
/** @param {Class} T */
constructor(T) { }
/** @returns {Promise.<T>} */
instance() {
// there will be complex async initialization at first call
// and Promise.resolve() at following calls
}
}
class Foo {
on() { }
off() { }
}
/** @type {Lazy.<Foo>} */
let foo = new Lazy(Foo);
foo.instance().then((i) => i.on());
foo.instance().then((i) => i.off());
最后两行揭示了我的问题 - 当我不确定 on()
是否会在 之前调用时,很难以这种方式使用
。Foo
实例>关闭()
最佳答案
您的实际问题:
Last two lines reveal my problem - it is difficult to work withFoo instance in that way when I am not sure that on() will be called before off().
你不应该依赖这个行为,相反你应该等待
获取实例然后缓存它:
async function withInstance() {
let instance = await foo.instance();
await instance.on();
await instance.off(); // guaranteed to be called after `.on`.
}
你问了什么
您可以依赖Job
的执行顺序。
当添加 promise then
时,它是一个 EnqueueJob
在规范中。引用 Jobs and Job Queues :
The PendingJob records from a single Job Queue are always initiated in FIFO order.
请注意,如果您有多个上下文(例如 - iframe 或 worker 之间的不同 promise ),则此保证不成立。
也就是说 - 强烈不建议依赖这样的执行顺序。
关于javascript - 我可以依赖非链式后续 promise 订单吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52067887/