Не могу понять поведение обещаний в JavaScript - PullRequest
0 голосов
/ 08 июня 2019

Кодовый блок 1 выполняется за 2 секунды.

Кодовый блок 2 выполняется за 4 секунды.

Может кто-нибудь объяснить, в чем разница между ними?

// Code block 1

const one = new Promise(resolve => setTimeout(() => resolve('one'), 2000));
const two = new Promise(resolve => setTimeout(() => resolve('two'), 2000));

(async() => {
  console.log(await one);
  console.log(await two);
})();

// Code block 2

const one = () => new Promise(resolve => setTimeout(() => resolve('one'), 2000));
const two = () => new Promise(resolve => setTimeout(() => resolve('two'), 2000));

(async() => {
  console.log(await one());
  console.log(await two());
})();

Ответы [ 2 ]

2 голосов
/ 08 июня 2019

В первом блоке кода оба Обещания немедленно инициализируются (когда объявляются one и two - у вас есть one = new Promise и two = new Promise), поэтому они оба разрешаются одновременно.

Во втором блоке кода Обещания создаются только после вызова функции.Поскольку await по существу блокирует асинхронную функцию, в

console.log(await one());
console.log(await two());

в await one() вы вызываете one, создаете Promise и ожидаете его разрешения.

Затем , после того, как это Обещание разрешено и его значение зарегистрировано, console.log(await two()) вызывает вторую функцию, , создавая Обещание , которое разрешается через пару секунд.

0 голосов
/ 08 июня 2019

Что ж, в некотором смысле нет никакой разницы между Обещаниями, все дело в том, когда они вызываются.

В первом блоке кода два Обещания вызываются немедленно, в тот момент, когда выполняются строки кода. Это означает, что таймер для Promise two (P2) запускается сразу после Promise one (P1). Таким образом, в этом примере вы ожидаете P1, через 2 секунды он завершается и переходит к проверке проверки, разрешен ли P2. В основном это так, потому что он работает в течение 2 секунд, поэтому печатает результат.

В этой небольшой модификации вы можете видеть, что я изменил таймер P2, чтобы он был короче, чем P1, однако он все равно будет печататься по порядку. Внутри вашего закрытия ваш код задерживается в ожидании разрешения P1, прежде чем он перейдет к проверке P2, как только он перейдет, он уже разрешится и немедленно выполнит обратный вызов разрешения, напечатав результат.

const one = new Promise(resolve => setTimeout(() => resolve('one'), 2000));
const two = new Promise(resolve => setTimeout(() => resolve('two'), 1000));

(async () => {
    console.log(await one);
    console.log(await two);
})();

Во втором блоке кода вы изначально не вызываете ни Promise, но назначаете функции переменные one & two - так что ни один таймер не запускается изначально. Первый console.log вызывает первую лямбда-функцию (P1) и ожидает ответ (который занимает 2 секунды), затем переходит на следующую строку и вызывает 'two', которая запускается и ожидает 2 секунды для ответа.

Важно помнить, что хотя код внутри созданного вами замыкания эффективно задерживается и ожидает разрешения Обещаний, выполнение программы будет продолжаться и за пределами замыкания. В приведенном ниже коде вы увидите сообщение, напечатанное немедленно, затем «один» и «два», через две и четыре секунды

const one = () => new Promise(resolve => setTimeout(() => resolve('one'), 2000));
const two = () => new Promise(resolve => setTimeout(() => resolve('two'), 2000));

(async () => {
    console.log(await one());
    console.log(await two());
})();
console.log ('Promises have been invoked: do other stuff while waiting');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...