Как JavaScript знает, как ждать результата внутреннего обещания? - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь обернуть голову невероятно запутанными темами Обещаний в Javascript.

Одно из сомнений, с которыми я столкнулся, заключается в том, что происходит, когда обратный вызов then() фактически возвращает обещание.

Посмотрите на приведенный ниже код, взятый из javascript.info

new Promise(function(resolve, reject) {

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

}).then(function(result) {

  alert(result); // 1

//Actually resolves before calling the next then()

  return new Promise((resolve, reject) => { // (*)
    setTimeout(() => resolve(result * 2), 1000);
  });

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

  alert(result); // 2

  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });

}).then(function(result) {

  alert(result); // 4

});

Любое из внутренних обещаний фактически выполняется перед переходом к следующему оператору then.

Почему это?Как Javascript узнает, когда возвращаемое значение является самим обещанием?

Есть ли действительно проверка в интерпретаторе JS для этого?Примерно так:

if(ret_value instanceof Promise) {
  wait_for_promise(ret_value);
}

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

Я пришел отЯвский фон, который, вероятно, поэтому меня раздражает эта свободная типизация.

Ответы [ 4 ]

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

По моему мнению, ответ @kaiido - это то, что вы ищете.

Упрощенно, реализация внутреннего обещания может выполнить такую ​​проверку:

if( typeof(retValue.then)==="function" ) {
    retValue.then( yourCallback );
}else{
    yourCallback( retValue );
}

Написал это на мобильном телефоне.Пожалуйста, извините за мое форматирование.

0 голосов
/ 30 мая 2018
Promise.resolve()
  .then(() => {
     return new Promise(res => setTimeout(() => res(1),1000))
   })
   .then(v => {
      console.log(v); //1
   });

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

Если вместо этого в первом then я возвратил значение (ниже), вместо Promise, JavaScript немедленно выполнил бы обратный вызов, который я передал второму then.

Promise.resolve()
  .then(() => {
     return 1
   })
   .then(v => {
      console.log(v); //1
   });

Почему это?Как Javascript узнает, что возвращаемое значение является самим обещанием?

Может быть, это может проиллюстрировать ответ на ваш вопрос:

let x = Promise.resolve();
console.log(x instanceof Promise); //true - JavaScript "knows" that x is a promise

let y = 1;
console.log(y instanceof Promise); //false
0 голосов
/ 30 мая 2018

Фактическая проверка выполняется против thenables , а не только против Promises .

Если возвращаемое значение преобразователя Promise имеет метод .then, этот метод будет вызван, и следующий обработчик / получатель получит значение этого метода в качестве аргумента:

const thenable = { // simple object, not an instance of Promise per se
  then: (res, rej) => setTimeout(() => res('from thenable'), 1000)
};
Promise.resolve(1)
  .then(v => thenable)
  .then(console.log)
0 голосов
/ 30 мая 2018

оператор return определяет, что следует передать следующему обещанию.если вы передаете любое другое значение, это будет сделано немедленно.но в этом случае вы передавали обещание.

return new Promise((resolve, reject) => {
setTimeout(() => resolve(result * 2), 1000);

});

и это обещание вернет значение в секунду.

resolve(result * 2)

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

...