admin管理员组文章数量:1391968
I'm trying to understand better what an async function
in JavaScript is technically, even if I basically know how to use them.
Many introductions to async/await make belive that an async
function is basically just a promise, but that obviously is not the case (at least not with Babel6-transpiled code):
async function asyncFunc() {
// nop
}
var fooPromise = new Promise(r => setTimeout(r, 1));
console.clear();
console.log("typeof asyncFunc is", typeof asyncFunc); // function
console.log("typeof asyncFunc.next is", typeof asyncFunc.next); // undefined
console.log("typeof asyncFunc.then is", typeof asyncFunc.then); // undefined
console.log("typeof fooPromise is", typeof fooPromise); // object
console.log("typeof fooPromise.next is", typeof fooPromise.next); // undefined
console.log("typeof fooPromise.then is", typeof fooPromise.then); // function
Still, it is definitely possible to await
a promise, like await fooPromise()
.
Is a
async funtion
a thing of it's own andawait
is simply patible with promises?and, is there a way to distinguish between a simple
function
and anasync function
at runtime (in a Babel-patible way)?
I'm trying to understand better what an async function
in JavaScript is technically, even if I basically know how to use them.
Many introductions to async/await make belive that an async
function is basically just a promise, but that obviously is not the case (at least not with Babel6-transpiled code):
async function asyncFunc() {
// nop
}
var fooPromise = new Promise(r => setTimeout(r, 1));
console.clear();
console.log("typeof asyncFunc is", typeof asyncFunc); // function
console.log("typeof asyncFunc.next is", typeof asyncFunc.next); // undefined
console.log("typeof asyncFunc.then is", typeof asyncFunc.then); // undefined
console.log("typeof fooPromise is", typeof fooPromise); // object
console.log("typeof fooPromise.next is", typeof fooPromise.next); // undefined
console.log("typeof fooPromise.then is", typeof fooPromise.then); // function
Still, it is definitely possible to await
a promise, like await fooPromise()
.
Is a
async funtion
a thing of it's own andawait
is simply patible with promises?and, is there a way to distinguish between a simple
function
and anasync function
at runtime (in a Babel-patible way)?
2 Answers
Reset to default 9An async function is a function that returns a promise. It helps you with cases where you have a bunch of asynchronous actions happening one after the other:
function asyncFunc() {
return doSomethingAsync() // doSomethingAsync() returns a promise
.then(() => {
// do some stuff
return doSomethingElseAsync(); // returns a promise
})
.then(something => {
// do some stuff
return doSomethingElseEntirelyAsync(something); // returns a promise
});
}
Turns to
async function asyncFunc() {
await doSomethingAsync(); // awaits for a promise
// do some stuff
let something = await doSomethingElseAsync(); // awaits for a promise
// do some stuff
return doSomethingElseEntirelyAsync(something); // returns the final promise
// Note that even if you return a value, like return 5, the function as a whole
// still returns a promise!
}
It reads a lot better, and you can use the normal tools like try/catch and for loops to work with them, even though they're async.
Async functions are NOT a replacement for promises, they're sugar on top of them, to handle specific cases where you have many sequential asynchronous actions.
Because await
is basically just "await for this promise", you can still use the cool aggregation methods like Promise.all()
and Promise.race()
and await for the result of several (or the first of several) promises.
I'm not familiar with a way of distinguishing the two in runtime because, like classes, async functions are just sugar on top of Promises. (Although there might be hacks like using the function's .toString
and parse the results, I don't count those).
The couple async/await
are a mechanism that let you write async code in an synchronous style and in my humble opinion it is the most simple and readable syntax so far to deal with asynchronous code (see also this article). The power of the syntax is really in how the await
works. But in order to use await
inside the body of a function, the function must have to be prefixed with async
.
If you need more information there is a spec for async/await
here.
The current implementation in Babel 5 is based on https://github./facebook/regenerator. As you can see in the transpiled code the function is piled to:
function asyncFunc(which, one, two) {
return regeneratorRuntime.async(function asyncFuncMaybe$(context$1$0) {
...
If you dig in Babel's babel-regenerator-runtime
package you find Facebook's code. At line 205 you find:
// Note that simple async functions are implemented on top of
// AsyncIterator objects; they just return a Promise for the value of
// the final result produced by the iterator.
runtime.async = function(innerFn, outerFn, self, tryLocsList) {
...
In order to transpile to ES5 the async/await
Babel needs do to rearrange the code so we can keep track where we are during the execution of the function and the AsyncIterator
is the object that keep track of that state.
Babel 6 gives you more options and let you choose the implementation that you want to use. See Transpile Async Await proposal with Babel.js?
So regarding your questions:
async/await
are both a thing of it's own. According to the spec, they must work with promises. In particular you canawait
on a promise and when you execute anasync
function, it will return you a promise.- Since an
async
function is transpiled to function that return a promise, there is not a straightforward way to distinguish it from a no-async function that return a promise. YourfooPromise
should look more likevar fooPromiseFunc = function() {return new Promise(r => setTimeout(r, 1))};
that makefooPromiseFunc
andasyncFunc
indistinguishable from a black box prospective. They are both functions that return a promise. What is the reason why you want to distinguish anasync
and no-async function at runtime? In practice they can be usedin the same way, so I do not see why you will have to threat them differently. For debug purposes if you really need to find out if a function is definedasync
, in Babel 5 you could use something like(asyncFunc+"").indexOf('regeneratorRuntime.async') > 0
or a more accurate regular expression. But that is really hacky and I would not use in a context outside of debugging or study.
本文标签: javascripttechnical difference between ES7 async function and a promiseStack Overflow
版权声明:本文标题:javascript - technical difference between ES7 async function and a promise? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744732881a2622151.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论