简体   繁体   English

异步标签是否将 JavaScript function 与 Promise 包装在一起?

[英]Does async tag wrap a JavaScript function with a Promise?

So I understand that "async" ensures that a function will return a Promise, and if it doesn't then it wraps it in a promise.所以我知道“异步”确保 function 将返回 Promise,如果没有,则将其包装在 promise 中。

My question is, if the function is already returning a Promise, does "async" wrap it in another Promise?我的问题是,如果 function 已经返回 Promise,“异步”是否将其包装在另一个 Promise 中?

async function, return non-Promise:异步 function,返回非承诺:

async function foo() {
    return 5;
}

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

regular function, return Promise:常规 function,返回 Promise:

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

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

async function, return Promise:异步 function,返回 Promise:

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

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

Why does the last one return "Promise { pending }" ?为什么最后一个返回"Promise { pending }" My intuition tells me the redundant "async" tag is wrapping the already returned Promise with another Promise.我的直觉告诉我,冗余的“异步”标签正在用另一个 Promise 包装已经返回的 Promise。 Is this correct?这个对吗?

If an async function returns a Promise, then the Promise returned by that function will resolve to the same value as the original Promise. If an async function returns a Promise, then the Promise returned by that function will resolve to the same value as the original Promise. This can be seen with a simple example:这可以通过一个简单的例子看出:

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

So in most normal situations, we can simply imagine that the Promise returned by the code inside the async function body is returned without being touched.所以在大多数正常情况下,我们可以简单的想象,async function body 里面的代码返回的 Promise 没有被触动。 But as you've stumbled across, even though the Promise returned by an async function will resolve to the same value as a Promise returned by the code, the actual Promise object is not necessarily the same: But as you've stumbled across, even though the Promise returned by an async function will resolve to the same value as a Promise returned by the code, the actual Promise object is not necessarily the same:

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

So we can see that the Promise object returned by the function invocation is actually different from the Promise object that the function body returned. So we can see that the Promise object returned by the function invocation is actually different from the Promise object that the function body returned. No matter, though, it will give the same result when we await it (or use Promise.then() ):无论如何,当我们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'

(Note that to run these examples in eg a node repl shell, you'll need to wrap them like: (请注意,要在例如节点 repl shell 中运行这些示例,您需要像这样包装它们:

async function main() {
  /* code using async / await here */
}
main();

You need to call your last function as:您需要将您的最后一个 function 称为:

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

The reason being, an async function needs to return a promise.原因是,异步 function 需要返回 promise。 A promise will log pending until the result is resolved. promise 将记录挂起,直到结果得到解决。 To capture the promise, you must call "then".要捕获 promise,您必须调用“then”。

Here is a link for more info about then: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then这是有关 then 的更多信息的链接: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

Here is a link for more info about async functinos: https://fmpapidev.holstein.ca/swagger/index.html这是有关异步函数的更多信息的链接: https://fmpapidev.holstein.ca/swagger/index.html

Now I'm not certain what the native implementation of async / await is for modern node apps but if you take a look at what Babel generates when it transpiles to node 6现在我不确定async / await的本机实现对于现代节点应用程序是什么,但如果你看看Babel在转译到节点 6 时会生成什么

Take this simple async function:以这个简单的异步 function 为例:

async function fooAsync() {
  return 1;
}

Babel transforms this code to look like this: Babel 将这段代码转换为如下所示:

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);
}

You can see the transformation of your async method and the state machine it generates.您可以看到异步方法的转换以及它生成的 state 机器。 The interesting part is that the generator, when executed, return a new Promise() .有趣的部分是生成器在执行时返回一个new Promise() So to answer your question, just having the keyword async in your function, would make it return a Promise .因此,要回答您的问题,只需在 function 中使用关键字async即可使其返回Promise This can also be seen in Typescript where the compiler will moan if you have an async method and you don't specify a return type of Promise<T>这也可以在Typescript中看到,如果你有一个async方法并且你没有指定Promise<T>的返回类型,编译器会抱怨

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM