Порядок исполнения в Promise () - PullRequest
0 голосов
/ 29 марта 2020

Программа - 1

new Promise(resolve => {
        resolve('1');
        Promise.resolve().then(() => console.log('2'));
    }).then(data => {
        console.log(data);
    }); // output 2 1

Программа -2

new Promise(resolve => {
        Promise.resolve().then(() => {
            resolve('1');
            Promise.resolve().then(() => console.log('2'));
        });
    }).then(data => {
        console.log(data);
    }); // output 1 2

Я действительно запутался с выводом обеих программ , Может кто-нибудь сказать, пожалуйста, как работает поток выполнения здесь?

Ответы [ 2 ]

0 голосов
/ 30 марта 2020

Разница заключается в том контексте, в котором находится событие l oop при разрешении обещания (resolve(1)).

Есть 2 очереди, которые выполняют код в JS:

  • микрозадача Q
  • макрозадача Q

JS выполняет микрозадачу и затем запускает все задачи из макрозадачи Q (если есть)

При разрешении обещания из executor (Promise (...)), который вы выполняете внутри macrotask Q. Код, выполняемый из обратного вызова обещания, выполняется в microtask Q .

Разница, которая имеет значение в этом случае, состоит в том, что при запуске изнутри микрозадачи Q, если вы добавляете другие микрозадачи (обратные вызовы обещаний являются микрозадачами), они добавляются к текущему Q и обрабатываются во время выполнения этой очереди.

Это то, что происходит в случае № 2, вы решаете обещание изнутри микрозадачи Q, это в конечном итоге разрешает верхний уровень Promise и добавляет .then(data => { log(data); }); к текущая микрозадача Q . Таким образом, обратный вызов будет выполнен в этом запуске. С другой стороны, обработчики вложенного обещания Promise.resolve() не выполняются , теперь , так как обработчики всегда называются asyn c.

Примечание: можно добавить микрозадачи. бесконечность изнутри микрозадачи Q, блокирующей выполнение.

0 голосов
/ 29 марта 2020

Трудно понять, что resolve не работает так же, как return. Создание Promises фактически создает новый асин * c контекст. Все внутри первой функции Promise выполняется синхронно. Затем методы .then() вызываются со значениями, разрешенными синхронно или асинхронно.

В первом примере вы разрешаете '1', но затем вы создаете новый Promise с помощью Promise.resolve() и вызываете .then() прямо сейчас. Поскольку новый Promise находится внутри первого, все вызывается синхронно.

new Promise(resolve => {
        resolve('1'); // Will be accessed in the .then() after then end of the callback
        Promise.resolve().then(() => log('2')); // called before the end of the function 
                                               // because the context is not yet created
    }).then(data => {
        log(data);
    }); // output 2 1

Второй пример гораздо сложнее. Вы фактически создаете Promise внутри первого Promise и сразу же вызываете его resolve. Порядок выполнения будет следующим:

  • сначала все в начальных обратных вызовах
  • После этого создайте сортировку eventListeners от resolve до .then
  • Когда вызывается resolve, выполнить обратный вызов в .then

В исходной функции вложенного promise ничего нет. Так что идет прямо к then. .then() вызывает начальный resolve(). Здесь создается вид eventListener, поэтому мы переходим к начальному обратному вызову. Затем мы go вернемся и выполним оставшуюся часть функции.

new Promise(resolve => {
        // Because we call resolve right away, the context of the original promise
        // is created
        Promise.resolve().then(() => {
            resolve('1'); // Calling resolve jumps us to the .then
            Promise.resolve().then(() => log('2')); // We execute after.then
        });
    }).then(data => {
        log(data);
    }); // output 1 2

Если вы удалите .resolve(), он будет работать как первый:

new Promise(resolve => {
        new Promise(() => {
            resolve('1');
            Promise.resolve().then(() => log('2'));
        });
    }).then(data => {
        log(data);
    }); // output 2 1
...