Является ли цепочка асинхронной цепочки обещаний? - PullRequest
0 голосов
/ 28 мая 2018

Как thenable цепочка асинхронна?Похоже, что promise, возвращенный из предыдущего Promise.then, блокирует (само намерение состоит в том, чтобы заблокировать в соответствии с приведенным ниже примером) следующий Promise.then в цепочке.Я новичок в promises в Node.js.Кто-нибудь может помочь мне лучше понять, как thenable цепочка асинхронная?
Из данного примера, почему мы не используем сами синхронные функции вместо thenable цепочек?

new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000); // (*)

}).then(function(result) { // (**)

  alert(result); // 1
  return result * 2;

}).then(function(result) { // (***)

  alert(result); // 2
  return result * 2;

}).then(function(result) {

  alert(result); // 4
  return result * 2;

});

Ответы [ 3 ]

0 голосов
/ 28 мая 2018

Позвольте мне ответить на этот почему вопрос.Если вы рассматриваете свой код, то это не имеет большого значения, вы могли бы просто отлично без обещаний.Вот так.

setTimeout(() => {
  let result = 1;
  alert(result);
  result *= 2;
  alert(result);
  result *= 2;
  alert(result);
  result *= 2;
}, 1000);

Но это потому, что код из setTimeout, код синхронный.Но представьте, если вы хотите связать асинхронные функции без обещаний.Вы все еще можете сделать это, но это приводит к довольно запутанному, трудно читаемому коду (адбэк обратного вызова).

Давайте посмотрим, как будет выглядеть ваш код в таком случае.

setTimeout(function() {
  let result = 1;
  alert(result);

  setTimeout((function(result) {
    result *= 2;
    alert(result);

    setTimeout((function(result) {
      result *= 2;
      alert(result);
    }).bind(null, result), 0);
  }).bind(null, result), 0);
}, 1000);

Он все еще делает то же самое, но выглядит намного хуже, чем код, использующий обещания.(И представьте, как бы это выглядело, если бы вы хотели связать больше, скажем, 10, таких функций)

0 голосов
/ 29 мая 2018

Цепочка then является асинхронной в том смысле, что код, следующий за цепочкой обещаний, будет выполнен без ожидания достижения обещания в своем разрешенном состоянии.

function sleep (ms) {
    return new Promise(resolve, setTimeout(resolve, ms));
}

// counts to 3 in 3 seconds, thanks to asynchronicity
sleep(3000).then(() => console.log('3'));
sleep(2000).then(() => console.log('2'));
sleep(1000).then(() => console.log('1'));

Метод thenданное обещание предоставляет способ присоединения любой функции, которая должна ожидать своего возвращаемого значения (*).Таким образом, цепочка обещаний представляет собой «синхронную последовательность инструкций», но она асинхронна по отношению к остальной части программы.

function add (i) {
    return sleep(1000)
        .then(() => { console.log(i+1); return i+1 });
}

// counts to 3 in 3 seconds, thanks to synchronicity along the chain
Promise.resolve(0).then(add).then(add).then(add);

Конечно, введение асинхронности было бы совершенно бесполезным, если бы приходилось иметь дело только с линейнымицепей.Релевантность появляется только при создании параллельных цепочек.Напротив, возьмем этот простой синхронный сценарий оболочки:

// counts *down* in 6 seconds
sleep 3; echo 3;
sleep 2; echo 2;
sleep 1; echo 1;

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

ВМежду тем асинхронность была бы невозможна, если бы не было удобного способа линеаризации задач, и некоторые куски кода ожидали друг друга.Обещания - это удобный способ для достижения этой цели, между прошлой "пирамидой обратного вызова" и последующими асинхронными ключевыми словами ECMA 2017, см., Например, .

(*) Beстарайтесь всегда возвращать что-то в промежуточные функции, иначе вся остальная часть цепочки может перестать ждать.

0 голосов
/ 28 мая 2018

Нет, это не блокирует вызов then().Все вызовы then() происходят сразу после создания обещания, и код продолжает выполняться синхронно.

Это только те then обратные вызовы , которые будут отложены асинхронно до тех пор, пока обещание не будетрешена.И каждый then() вызов возвращает новое обещание для результата обратного вызова, так что вы можете связать их вместе, и каждый обратный вызов будет вызываться после другого.

Но блокирования нет:

console.log("creating the first promise");
var promise = new Promise(function(resolve, reject) {
    console.log("starting the timeout")
    setTimeout(() => {
        console.log("resolving the first promise");
        resolve(1);
    }, 1000);
});
console.log("installing the callback");
var nextPromise = promise.then(function(result) {
    console.log("receiving the result", result);
    return result * 2;
});
console.log("continuing synchronously after the then() call");

// and so on with
// nextPromise.then(nextResult => console.log("receiving second result", result));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...