JavaScript Promise then() заказывает

Я все еще изучаю 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>

Ответ 1

Причина, по которой вы видите 6 раньше, - это то, что вы не цепко, вы разветвлены.

Когда вы вызываете p.then().then().then(), у вас есть цепочка promises, которая должна выполняться в правильном порядке.
Однако, если вы вызываете p.then().then(); p.then(), у вас есть 2 promises, прикрепленный к p - по существу, создавая ветвь, а вторая ветвь будет выполняться вместе с первой.

Вы можете исправить это, гарантируя, что вы объедините их вместе p = p.then().then(); p.then();

FYI, вы почти НИКОГДА не хотите вступать в ветки, если вы не вернете их вместе (например, Promise.all) или намеренно создаете ветвь "огонь и забыть".

Ответ 2

Что делает 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);
});