Почему ожидание Promise.resolve (v) дает вам v, а не ожидание дает вам обещание? - PullRequest
0 голосов
/ 01 февраля 2019

Когда я делаю это:

const p = Promise.resolve(‘hello world’);
console.log(p);

Я получаю это для вывода:

ZoneAwarePromise {__zone_symbol__state: true, __zone_symbol__value: "hello world"}
__zone_symbol__state: true
__zone_symbol__value: "hello world"
__proto__: Object

Но если я делаю это:

const p = await Promise.resolve(‘hello world’);

Я получаю этодля вывода:

hello world

Почему, когда я не жду Promise.resolve (…), p - это обещание, но когда я делаю, p - это значение, к которому разрешается обещание?

Я спрашиваю, потому что из того, что я понимаю, Promise.resolve (…) не асинхронный, что означает, что он разрешается сразу.Следовательно, не должно ли p просто быть значением 'hello world' в обоих случаях?Что ждет, если обещание уже выполнено?Другими словами: что происходит между моментом, когда обещание разрешено, и временем, когда оно дает вам решенную ценность?И что вызывает это?

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Функция Promise.resolve(val) специально разработана для возврата объекта Promise.Вот для чего он предназначен.Итак, когда вы делаете:

const p = Promise.resolve('hello world');
console.log(p);

Переменная p содержит именно то, что Promise.resolve() предназначено для возврата, объект обещания.

Этот объект обещания уже разрешен внутренне, но когда вы проверяете возвращаемое значение, вы видите объект Promise.

Как и для ВСЕХ объектов обещания, если вы хотите получить разрешенное значение из объекта обещания, вы должны использовать .then() или await чтобы получить доступ к значению.Обещание, возвращенное с Promise.resolve(), ничем не отличается в этом отношении от любого другого обещания.

const p = Promise.resolve('hello world');
console.log(p);           // shows you the promise object

p.then(val => {
    console.log(val);     // 'hello world'
});

// or this
console.log(await p);     // 'hello world'

Почему, когда я не жду Promise.resolve (…), pобещание, но когда я это сделаю, p - это значение, в которое разрешается обещание?

Поскольку Promise.resolve() всегда возвращает объект обещания, а await p возвращает значение этого объекта обещания.

Я спрашиваю, потому что, насколько я понимаю, Promise.resolve (…) не асинхронный, что означает, что он разрешается сразу.Следовательно, не должно ли p просто быть значением 'hello world' в обоих случаях?Что ждет, если обещание уже выполнено?Другими словами: что происходит между моментом, когда обещание разрешено, и временем, когда оно дает вам решенную ценность?И что вызывает это?

Вы используете Promise.resolve(), когда то, что вы ХОТИТЕ, является объектом обещания, который уже находится в разрешенном состоянии.Если вам просто нужно значение, вы вообще не используете Promise.resolve().Так что, как правило, в коде нет смысла:

const val = await Promise.resolve('hello world');

Вы можете просто сделать это:

const val = 'hello world';

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

 const cache = new Map();
 const rp = require('request-promise');

 function getData(id) {
     // see if we already have the result in the cache
     if (cache.has(id)) {
         // if so, return a promise that is resolved with our cached value
         return Promise.resolve(cache.get(id));
     } else {
         return rp(myURL + "?id=" + id).then(data => {
             // cache the value
             cache.set(id, data);
             return data;
         });
     }     
 }

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

Затем вызывающая сторона может всегда всегда использовать возвращаемое обещание, не имея необходимости знать, было ли кэшировано значение или нет:

 getData("price").then(val => {
     console.log(val);
 }).catch(err => {
     console.log(err);
 });
0 голосов
/ 01 февраля 2019

Это именно то, что делает await.В некотором смысле это можно рассматривать как «развертывание» Обещания - семантически, вы ожидаете разрешения Обещания и затем получаете разрешенное значение.В результате вы можете использовать await только внутри асинхронной функции (обозначенной ключевым словом async), которая возвращает возвращаемое значение этой функции себе Promise.

Так, например:

async function example() {
  return await promise;
}

функционально эквивалентно:

function example() {
  return promise.then(result => {
   return result;
  })
}
...