据我所知,promise是可以resolve((或reject((的东西,这个操作应该在完成一些工作后完成,所以它应该作为回调的一部分调用,就像本例中那样:
let timeout = new Promise((resolve) => {
console.log('function called');
setTimeout(() => {
console.log("timeout finisced!");
resolve()
}, 1000)
});
timeout.then(() => {
console.log("timeout resolved!")
});
console.log('teminated!');
结果
function called
teminated!
timeout finisced!
timeout resolved!
但我不明白的是,当没有异步操作要做时,它们是如何工作的,因此,如果你同步思考,那么解析函数应该在promise的构造函数中调用,即使你没有它的处理程序,然后then()
方法应该能够处理它;但从这个例子中我可以看到,代码是以同样的方式执行的。那么,有人能解释为什么下面的例子以这种方式工作的背后想法吗?
new Promise(function(resolve) {
console.log('function called')
resolve();
}).then(() => {
console.log('function resolved');
});
console.log('teminated!');
结果:
function called
teminated!
function resolved
编辑:
我基本上了解了正在发生的事情,但现在我不确定是如何做到的。所以,如果我错了,请纠正我,.then()
方法无论如何都会放在micro task queue
中,所以即使你给它传递同步代码,它也不会像其他同步代码一样直接在堆栈中执行。为了实现这一点,应该实现或拒绝promise的状态,为此应该调用函数resolve()
或reject()
。所以现在我想了解它背后的过程,比如then() method
能有效地做什么?你给它传递了一个回调,它存储在promise对象中,或者什么?因为回调是在完成或拒绝后放在微任务队列中的,这是否意味着是resolve()
函数将其放在了微任务队列?基于下面的例子,这应该是一个合理的假设;还是解析函数只改变状态,然后是then() method
将其放入队列?
const p = Promise.resolve();
p.then(() => console.log("callback 1"));
const p2 = Promise.resolve();
p2.then(() => console.log("other micro task"));
p.then(() => console.log("callback 2"));
/*
result:
callback 1
other micro task
callback 2
*/
const p = Promise.resolve();
p.then(() => console.log("callback 1"));
const p2 = new Promise((resolve) => {
setTimeout(() => resolve(), 0)
});
p2.then(() => console.log("other micro task"));
p.then(() => console.log("callback 2"));
/*
result:
callback 1
callback 2
other micro task
*/
我唯一确信的是,一个承诺有多个回调,它们并不总是按顺序一个接一个地执行,但在它之前可能会有另一个微任务,就像第一个例子中一样。
我知道这可能是一个愚蠢的问题,但出于某种原因,它让我感到困惑,所以提前感谢我们的帮助。
首先,promise是异步的(then
部分(,async/await构建在它们之上。promise不是一个简单的异步代码,而是一个微任务,它在同步代码之后执行,但在宏任务(如超时(之前执行。因此,在您的情况下,我们有同步承诺部分function called
,比同步代码teminated
,比承诺解决后的异步部分function resolved
。
为了更好地了解微/微任务和事件循环是如何工作的,我建议您在这里查看答案:事件循环上下文中的微任务和宏任务之间的区别