我试图更好地理解async function在JavaScript中是什么技术,即使我基本上知道如何使用它们。
关于异步/等待的许多介绍都使人相信,async函数基本上只是一种承诺,但情况显然并非如此(至少在Babel6 6-转置码中并非如此):
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不过,await是绝对有可能的,就像await fooPromise()一样。
async funtion是它自己的东西,而await只是与承诺兼容吗?function和async function (以Babel兼容的方式)?发布于 2016-01-12 09:38:35
异步函数是一个返回承诺的函数。它可以帮助您处理一组异步操作一个接一个地发生的情况:
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
});
}转到
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!
}它读起来要好得多,您可以使用普通的工具,如try/catch和for循环来处理它们,即使它们是异步的。
异步函数是,而不是,它是承诺的替代品,它们是最重要的,用于处理有许多顺序异步操作的特定情况。
因为await基本上只是“等待这个承诺”,所以您仍然可以使用像Promise.all()和Promise.race()这样的冷静的聚合方法,并等待多个承诺(或多个承诺中的第一个)的结果。
我不熟悉在运行时区分这两者的方法,因为与类一样,异步函数只是承诺之上的糖。(虽然可能存在一些黑客,比如使用函数的.toString并解析结果,但我不计算这些)。
发布于 2016-01-12 11:37:54
耦合async/await是一种允许您以同步方式编写异步代码的机制,在我看来,它是迄今为止处理异步代码的最简单和最易读的语法(请参见这篇文章)。语法的强大之处在于await的工作方式。但是,为了在函数的正文中使用await,函数必须以async作为前缀。
如果您需要更多信息,就会有一个这里。
Babel 5中的当前实现是基于https://github.com/facebook/regenerator的。正如您在转置码中看到的那样,该函数被编译为:
function asyncFunc(which, one, two) {
return regeneratorRuntime.async(function asyncFuncMaybe$(context$1$0) {
...如果你挖掘巴贝尔的babel-regenerator-runtime包,你会发现Facebook的代码。在第205项,您可以找到:
// 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) {
...为了传输到ES5,async/await Babel需要做些什么来重新排列代码,这样我们就可以在函数执行期间跟踪我们所处的位置,而AsyncIterator是跟踪该状态的对象。
Babel 6为您提供了更多的选项,并允许您选择要使用的实现。请参阅Transpile异步等待提案与Babel.js?
因此,关于你的问题:
async/await都是它自己的东西。根据规范,他们必须履行承诺。特别是,您可以在一个承诺上执行await,并且当您执行一个async函数时,它将返回一个承诺。async函数被转换为返回承诺的函数,所以没有一种简单的方法来区分它与返回承诺的非异步函数。您的fooPromise应该更像var fooPromiseFunc = function() {return new Promise(r => setTimeout(r, 1))};,这使得fooPromiseFunc和asyncFunc与黑匣子很难区分开来。它们都是回报承诺的函数。为什么要在运行时区分async和非异步函数?在实践中,他们可以以同样的方式使用,所以我不明白你为什么要以不同的方式威胁他们。为了调试目的,如果您确实需要了解函数是否定义为async,那么在Babel 5中,您可以使用类似于(asyncFunc+"").indexOf('regeneratorRuntime.async') > 0或更精确的正则表达式。但这实在是太麻烦了,我不会在调试或学习之外的上下文中使用。https://stackoverflow.com/questions/34739883
复制相似问题