Я запутался из-за того, что новый Promise ((разрешить, отклонить) => {[loop]}) блокируется, а Promise.resolve (). Then ([loop]) нет - PullRequest
1 голос
/ 10 апреля 2019

У меня есть три теста с использованием встроенной функции console.time (beforeBenchmark, benchmark и afterBenchmark).

Оба кода совершенно идентичны. Однако разница заключается в создании API JS Promises.

Первый содержит цикл в разрешении Обещания, а второй - цикл в Обещании.

Я не уверен, почему третий console.log («после цикла») занимает значительно больше времени для завершения, что я разработал, чтобы это было асинхронным. Спасибо за ваше время, чтобы прочитать это.

Обещание Разрешить

перед циклом
beforeBenchmark: 0,836мс
после цикла
afterBenchmark: 40,987мс
тест: 41.202мс

Обещай тогда

перед циклом
beforeBenchmark: 1.122ms
после цикла
afterBenchmark: 2,872 мс
тест: 43,705мс

Я осмотрел переполнение стека, но не смог найти ответа на этот вопрос.

Первый тип обещания

console.time("beforeBenchmark");
console.time("benchmark");
console.time("afterBenchmark");
console.log("before loop");
console.timeEnd("beforeBenchmark");

let i = 0;

let promise = new Promise(( resolve, reject ) =>
{
    while (i < 10000000)
    {

        i++;
    }

    resolve();

}).then(() =>
{    
    console.timeEnd("benchmark")

});

console.log("after loop");
console.timeEnd("afterBenchmark");

Результат

before loop
beforeBenchmark: 0.836ms
after loop
afterBenchmark: 40.987ms
benchmark: 41.202ms

Второй тип обещания

console.time("beforeBenchmark");
console.time("benchmark");
console.time("afterBenchmark");
console.log("before loop");
console.timeEnd("beforeBenchmark");
let i = 0;

let promise = Promise.resolve().then(() =>
{
    while (i < 10000000)
    {
        i++;
    }

    console.timeEnd("benchmark")
});


console.log("after loop");
console.timeEnd("afterBenchmark");

Результат

before loop
beforeBenchmark: 1.122ms
after loop
afterBenchmark: 2.872ms
benchmark: 43.705ms

1 Ответ

2 голосов
/ 10 апреля 2019

Конструктор Promise выполняется синхронно.Если у вас есть код блокировки внутри new Promise(..., этот код будет выполняться (и блокироваться) до запуска следующей строки под созданным Promise.Вот почему ваш первый фрагмент имеет afterBenchmark: 40.987ms.

С другой стороны, обратный вызов .then будет запускаться только только после того, как текущий цикл обработки событий будет очищен (после того, как весь синхронный код имеетзакончил выполнение) - это похоже на setTimeout(fn, 0) (не точно то же самое, поскольку setTimeout будет выполняться на следующей итерации цикла * * * * , а не в конце текущегопетля, но это довольно похоже).Таким образом, afterBenchmark во втором коде регистрируется до запуска then, до запуска цикла блокировки.

...