Fai*_*eef 2 javascript promise
对于以下代码
function inner () {
new Promise(function(resolve,reject){
resolve()
}).then(function(){
console.log('Inner Promise')
})
}
function outer() {
return new Promise(function(resolve, reject){
resolve()
inner()
})
}
outer().then(function(data) {
console.log('Outer Promise')
})
Run Code Online (Sandbox Code Playgroud)
输出是
Inner Promise
Outer Promise
Run Code Online (Sandbox Code Playgroud)
我认为外部决心将是第一个进入JS Message Queue,然后是内部解析.然而,JS事件循环首先触发内部解析,然后是外部解析.
Promise在内部解决了什么?
简而言之,你得到你所看到的行为,因为.then()在法inner()诺首先运行之前.then()对法outer()的承诺,因此它的处理程序得到第一个排队(见下文为什么这是一步一步的解释).
Promise在内部解决了什么?
resolve()将承诺的内部状态更改为已实现.此时,如果有任何.then()处理程序已附加到promise,它们将被添加到队列中,以便在堆栈展开并且Javascript的当前运行路径完成并将控制权返回给系统时执行.请注意,正如您将在本例中看到的那样(当您阅读下面的逐步分析时),如果还没有任何.then()已注册的处理程序,则还没有任何内容可以添加到队列中.
我认为外部决心将是第一个进入JS Message Queue,然后是内部解析.然而,JS事件循环首先触发内部解析,然后是外部解析.
Promise解决操作未添加到队列中. resolve()是同步的.它立即将当前承诺的状态更改为Fulfilled状态.如果在解析promise时,已经有任何.then()处理程序已经注册,那么它们就是添加到队列中的内容.但是,在你的承诺中,在你的每一个承诺得到解决的那一刻,还没有.then()附加的处理程序.因此,这些.then()处理程序不会在承诺得到解决时排队.相反,当.then()方法实际运行并注册它们时,它们将在稍后排队.
以下是对代码运行方式的分析以及可能的解释:
outer().这将创建一个Promise对象并同步调用您传递它的promise executor回调. resolve()将排队调用任何当前连接的.then()处理程序.请注意,在您调用的那一刻resolve(),还没有.then()处理程序,因为在此代码中outer().then(),您仍然在运行outer()并且.then()尚未运行,因此实际上还没有任何排队的事情(这可能是关键您观察的顺序 - 请继续阅读以获取更多详细信息).inner().这创建了一个新的promise,然后(仍然同步运行)调用你传递给它的promise执行器回调调用resolve().同样,还没有任何.then()处理程序附加,所以仍然没有其他任何安排以便将来执行.inner()返回内部的Promise执行者和.then()方法在内部的promise上被调用inner().此承诺已经解决,因此,当.then()调用此处理程序时,承诺知道将其安排在将来运行.由于.then()当堆栈仅展开到平台代码时,所有处理程序都是异步调用的,因此它不会立即运行,而是计划在将来通过将其置于队列中来运行.它的实现依赖于这个队列的工作原理(宏任务或微任务等等),但是我们知道Promise规范可以保证它在执行的当前同步JS代码之后运行并完成运行并返回控制回到系统.inner()返回(代码仍在同步运行).outer()返回并运行.then()方法outer().then().与前面的示例一样,.then()调用此方法时,主机承诺已经解决.因此,promise引擎将.then()通过将处理程序回调添加到队列来安排处理程序回调..then()步骤4和6中的这两个处理程序按照它们运行的顺序排队(这将是逻辑实现),那么您将首先看到.then()处理程序inner(),然后.then()处理程序outer()将从inner().then() ran first beforeouter()开始运行.然后() `.这就是你观察到的.outer()之前inner()已经outer()解决,但在解决时,还没有.then()附加处理程序,因此在解决时无需安排将来执行.这可能是为什么即使首先解决它,它的.then()处理程序也不会先运行.一旦两个inner()和outer()都解决了,这是内在的.then()运行第一种方法,因此它的第一次尝试在调度.then()处理程序来运行,这是你看到的东西.您可以通过阅读和研究这些参考资料获得一些额外的背景信息:
如果您想更明确地指定内部.then()处理程序将首先触发,您可以简单地将其链接到outer()承诺,如下所示:
function inner () {
return new Promise(function(resolve,reject){
resolve();
}).then(function(){
console.log('Inner Promise')
})
}
function outer() {
// Add return here to chain the inner promise
// make to make sure that outer() does not resolve until
// inner() is completely done
return inner();
}
outer().then(function(data) {
console.log('Outer Promise')
})Run Code Online (Sandbox Code Playgroud)
如果你想保证outer().then()首先调用处理程序,你必须选择一个不同的结构,因为这个结构不会以任何方式强制这种类型的顺序,并且不能被指向那个方向,除非你有意识地延迟运行inner()(使用setTimeout()或某些此类事物)或重组代码.例如,如果你真的想重组以强制inner()最后运行,你可以在这样的outer().then()处理程序中启动它:
function inner () {
return new Promise(function(resolve,reject){
resolve()
}).then(function(){
console.log('Inner Promise')
})
}
function outer() {
return new Promise(function(resolve, reject){
resolve()
})
}
outer().then(function(data) {
console.log('Outer Promise')
return inner();
})Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1863 次 |
| 最近记录: |