Обсуждает ли тег asyn c функцию JavaScript с помощью Promise? - PullRequest
1 голос
/ 22 апреля 2020

Итак, я понимаю, что «asyn c» гарантирует, что функция вернет Обещание, а если нет, то обернет его в обещание.

У меня вопрос, если функция уже возвращая обещание, "asyn c" переносит его в другое обещание?

asyn c, возвращает не обещание:

async function foo() {
    return 5;
}

console.log(foo()) // Promise { 5 }

обычная функция, возвращает Обещание:

function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { 5 }

asyn c функция, возвращает Обещание:

async function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { <pending> }

Почему последний return "Обещание в ожидании" ? Интуиция подсказывает, что избыточный тег «asyn c» оборачивает уже возвращенное обещание другим обещанием. Это правильно?

Ответы [ 3 ]

2 голосов
/ 22 апреля 2020

Если функция async возвращает Обещание, то Обещание, возвращаемое этой функцией, преобразуется в то же значение, что и исходное Обещание. Это можно увидеть на простом примере:

async function foo() {
  return Promise.resolve(42);
}
console.log(await foo()); // "42", not "Promise { 42 }"

Так что в большинстве обычных ситуаций мы можем просто представить, что Promise, возвращаемый кодом внутри тела функции asyn c, возвращается без прикосновения. Но, как вы и наткнулись, даже несмотря на то, что Promise, возвращаемый асинхронной c функцией, будет преобразован в то же значение, что и Promise, возвращаемый кодом, фактический объект Promise не обязательно будет таким же:

let p1;
async function foo() {
  p1 = Promise.resolve(42);
  return p1;
}
let p2 = foo();
console.log('p1 === p2 ?', p1 === p2); // "false" (!)

Итак, мы видим, что объект Promise, возвращаемый вызовом функции, на самом деле отличается от объекта Promise, возвращаемого телом функции. Однако независимо от того, что он даст тот же результат, когда мы await его (или используем Promise.then()):

let p1;
async function foo() {
    p1 = Promise.resolve(42);
    return p1;
}
let p2 = foo();

console.log(await p1); // '42'
console.log(await p2); // also '42'

(обратите внимание, что для запуска этих примеров, например, в оболочке repl узла, вы ' Вам нужно будет обернуть их как:

async function main() {
  /* code using async / await here */
}
main();
0 голосов
/ 22 апреля 2020

Теперь я не уверен, какова нативная реализация async / await для современных приложений для узлов, но если вы посмотрите на то, что Babel генерирует при переносе на узел 6

Возьмем эту простую асинхронную c функцию:

async function fooAsync() {
  return 1;
}

Вавилон преобразует этот код так:

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function fooAsync() {
  return _fooAsync.apply(this, arguments);
}

function _fooAsync() {
  _fooAsync = _asyncToGenerator(function* () {
    return 1;
  });
  return _fooAsync.apply(this, arguments);
}

Вы можете увидеть преобразование вашего асинхронного c метода и конечный автомат он генерирует. Интересная часть заключается в том, что генератор при запуске возвращает new Promise(). Поэтому, чтобы ответить на ваш вопрос, просто наличие ключевого слова async в вашей функции вернуло бы Promise. Это также можно увидеть в Typescript, где компилятор будет стонать, если у вас есть метод async, и вы не указываете тип возврата Promise<T>

0 голосов
/ 22 апреля 2020

Вам нужно вызвать вашу последнюю функцию как:

foo.then(function(r){console.log(r)});

Причина в том, что асиновая c функция должна возвращать обещание. Обещание будет регистрироваться в ожидании, пока результат не будет решен. Чтобы получить обещание, вы должны позвонить «тогда».

Вот ссылка для получения дополнительной информации о: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

Ссылка для получения дополнительной информации об asyn c functinos: https://fmpapidev.holstein.ca/swagger/index.html

...