首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ES7异步功能与承诺的技术差异?

ES7异步功能与承诺的技术差异?
EN

Stack Overflow用户
提问于 2016-01-12 09:30:46
回答 2查看 1.5K关注 0票数 7

我试图更好地理解async function在JavaScript中是什么技术,即使我基本上知道如何使用它们。

关于异步/等待的许多介绍都使人相信,async函数基本上只是一种承诺,但情况显然并非如此(至少在Babel6 6-转置码中并非如此):

代码语言:javascript
复制
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只是与承诺兼容吗?
  • 还有,在运行时是否有一种方法来区分简单的functionasync function (以Babel兼容的方式)?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-12 09:38:35

异步函数是一个返回承诺的函数。它可以帮助您处理一组异步操作一个接一个地发生的情况:

代码语言:javascript
复制
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
    });
}

转到

代码语言:javascript
复制
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并解析结果,但我不计算这些)。

票数 9
EN

Stack Overflow用户

发布于 2016-01-12 11:37:54

耦合async/await是一种允许您以同步方式编写异步代码的机制,在我看来,它是迄今为止处理异步代码的最简单和最易读的语法(请参见这篇文章)。语法的强大之处在于await的工作方式。但是,为了在函数的正文中使用await,函数必须以async作为前缀。

如果您需要更多信息,就会有一个这里

Babel 5中的当前实现是基于https://github.com/facebook/regenerator的。正如您在转置码中看到的那样,该函数被编译为:

代码语言:javascript
复制
function asyncFunc(which, one, two) {
  return regeneratorRuntime.async(function asyncFuncMaybe$(context$1$0) {
...

如果你挖掘巴贝尔的babel-regenerator-runtime包,你会发现Facebook的代码。在第205项,您可以找到:

代码语言:javascript
复制
// 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))};,这使得fooPromiseFuncasyncFunc与黑匣子很难区分开来。它们都是回报承诺的函数。为什么要在运行时区分async和非异步函数?在实践中,他们可以以同样的方式使用,所以我不明白你为什么要以不同的方式威胁他们。为了调试目的,如果您确实需要了解函数是否定义为async,那么在Babel 5中,您可以使用类似于(asyncFunc+"").indexOf('regeneratorRuntime.async') > 0或更精确的正则表达式。但这实在是太麻烦了,我不会在调试或学习之外的上下文中使用。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34739883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档