JavaScript Promise then() ordering
JavaScript Promise then() ordering
我仍在学习JavaScript Promise
s,遇到了一个我不理解的行为。
var o = $("#output");
var w = function(s) {
o.append(s + "<br />");
}
var p = Promise.resolve().then(function() {
w(0);
}).then(function() {
w(1);
});
p.then(function() {
w(2);
return new Promise(function(r) {
w(3);
r();
}).then(function() {
w(4);
});
}).then(function() {
w(5);
});
p.then(function() {
w(6);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"></div>
我希望这些语句按顺序运行——也就是说,输出将是
0
1
2
3
4
5
6
相反,输出是
0
1
2
3
6
4
5
即使删除内部Promise
,在我看来也会产生矛盾的结果。1
在2
之前输出,但6
在5
之前输出。
有人能向我解释一下吗?
我注意到,每次重新分配p
都会给我们带来我所期望的顺序。
您早期看到6
的原因是因为您没有连锁,而是分支。
当您调用p.then().then().then()
时,您得到了一系列承诺,必须以正确的顺序执行这些承诺
然而,如果您调用p.then().then(); p.then()
,那么p
附带了两个promise——本质上是创建一个分支,第二个分支将与第一个分支一起执行。
您可以通过确保将它们链接到p = p.then().then(); p.then();
来解决此问题
仅供参考,你几乎从不想分支,除非你把它们重新组合在一起(例如Promise.all
),或者有意创建一个"着火后忘记"的分支。
r()做什么?
排序是不确定的,因为你当时在同一个承诺上->这具体指的是第二个和第三个链。
如果您正在执行以下操作,则订单可以得到保证:
var p = Promise.resolve().then(function() {
w(0);
}).then(function() {
w(1);
});
// Key difference, continuing the promise chain "correctly".
p = p.then(function() {
w(2);
return new Promise(function(r) {
w(3);
r();
}).then(function() {
w(4);
});
}).then(function() {
w(5);
});
p.then(function() {
w(6);
});
为了清楚起见,让我们为示例中的每个承诺和函数命名:
var pz = Promise.resolve();
function f0() { w(0); }
var p0 = pz.then(f0);
function f1() { w(1); }
var p1 = p0.then(f1); // p1 is 'p' in your example
function f2() {
w(2);
function f3(resolve_p3) {
w(3);
resolve_p3();
}
var p3 = new Promise(f3);
function f4() { w(4); }
var p4 = p3.then(f4);
return p4;
}
var p2 = p1.then(f2);
function f5() { w(5); }
var p5 = p2.then(f5);
function f6() { w(6); }
var p6 = p1.then(f6);
让我们一步一步来看看会发生什么。首先是顶级执行:
pz
被满足,因此pz.then(f0)
立即将f0
排队执行,其结果将解析p0
- 一旦满足
p0
,则调度f1
排队,并且其结果将解析p1
- 一旦满足
p1
,则调度f2
排队,并且其结果将解析p2
- 一旦满足
p2
,则调度f5
排队,并且其结果将解析p5
- 一旦满足
p1
,则调度f6
排队,并且其结果将解析p6
然后将运行排队的作业(最初仅为f0
):
- 执行
f0
:打印"0"。p0
被满足,因此f1
被添加到队列中 - 执行
f1
:打印"1"。p1
被满足,因此f2
和f6
被添加到队列(按顺序)。这是关键的一位,因为这意味着f6
将在稍后排队的任何作业之前执行 - 执行
f2
:打印"2" - (在
f2
内部):new Promise
调用f3
,后者打印"3"并实现p3
- (在
f2
内部):由于p3
已经完成,所以将f4
添加到队列中,其结果将解析p4
f2
最终将p2
解析为p4
,这意味着一旦满足p4
,p2
也将满足- 执行
f6
:打印"6"。CCD_ 54变为满足 - 执行
f4
:打印"4"。CCD_ 56变为满足。p2
被满足,因此f5
被添加到队列中 - 执行
f5
:打印"5"。CCD_ 60被满足
相关文章:
- Javascript:If-then语句在函数中不起作用
- angularjs无法读取未定义的属性then
- Promise函数在.then之后未运行函数化
- 为什么$.when().pipe().then()有效,而$.when
- 如何在异步函数中正确使用Promise.all()和then()
- $resource上带有.then()函数的角度自定义方法导致错误
- 可以链接 '.then() 的返回响应,顺序与 '.then()' 的顺序不同
- AngularJS因果报应测试规范承诺未解析,且未调用.then()
- 在javascript promise中正确使用then
- 将数据从promise then方法传递到对象方法
- Angular Provider/JS-如何访问'叔叔方法'从$http().then()
- 当链接javascript承诺时,如何处理then()函数中的条件
- JavaScript Promise then() ordering
- linq.js: GroupBy(), then ToJSON()
- pipe() 和 then() 文档与 jQuery 1.8 中的现实
- 角承诺的“then”函数的成功回调的词汇范围是什么?
- 为什么 then() 链式方法不按顺序运行
- Node.js Promise - 代码不应该等到 .then 完成()
- “未捕获(在承诺中)”在获取“then”方法中调用拒绝函数时
- 我如何访问在 Angular JS 的 .then() 中定义的$scope数组