我一直在使用Babel一段时间,我很喜欢它。但是,在主页上列出了支持的功能,它显示Async functions
。
我做了很多谷歌搜索,而我似乎只能理解它是一个ES7功能。
请问什么是ES7异步功能?
答案 0 :(得分:5)
异步等待与ES6 Promises一起使用。您可以将它们视为使用Promises编写同步代码的方法。
async
关键字标记为将进行异步调用的方法。 await
关键字标记实际的通话。
有了一个承诺,你需要将一个方法传递给promise的.then()
方法来处理结果。
function doSomethingAsync() {
return new Promise((resolve, reject) => {
// call Rest service and resolve here
})
}
function printResult() {
doSomethingAsync()
.then(result => console.log(result));
}
一切正常。使用Async/Await
,我们可以将最后一个函数编写得有点不同。
async function printResult() {
let result = await doSomethingAsync();
console.log(result);
}
这样做的好处是它只是减少了回调的需要。
有关详情,请参阅:https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html
答案 1 :(得分:1)
ES2016(通常称为ES7或ECMAScript 7)是ECMA-262标准(通常称为JavaScript)的下一个演变,并且仍处于早期阶段。
异步功能是一种新的JavaScript功能,作为ES2016标准的一部分提出,但尚未得到任何浏览器的支持。它们建立在promises之上。
请参阅下文,了解各种权威来源对此新功能的介绍。
即使异步函数通常被称为ES7 asynch functions
(例如,通常将async.js或asynchronous JavaScript消除歧义),Axel Rauschmayer建议使用not calling them that但是,作为一项功能,只有在其提案达到第4阶段时才会包含在下一个标准中。
异步功能现在只在第3阶段。事实上,ES2016可能not contain async functions(正如Felix Kling在下面的评论中指出的那样。)
简介
ECMAScript中的承诺和生成器的介绍提出了一个 大大改善语言水平模型的机会 在ECMAScript中编写异步代码。
期间与Deferred Functions提出了类似的提案 ES6讨论。这里的提议支持使用相同的用例 类似或相同的语法,但直接建立在控制流程上 与发电机平行的结构,并使用承诺 返回类型,而不是定义自定义机制。
该提案的制定工作正在进行中 https://github.com/tc39/ecmascript-asyncawait。请提出问题 那里。非平凡的贡献仅限于TC39成员,但拉动 欢迎并鼓励小问题的请求!
此提案的状态
该提案被接纳为第3阶段("候选人") 2015年9月ECMAScript spec process。冠军 打算将此提案纳入第4阶段("已完成") 11月底。
实施例
采用以下示例,首先使用Promises编写。这段代码 链接元素上的一组动画,当有元素时停止 动画中的异常,并返回由...生成的值 最终成功执行的动画。
function chainAnimationsPromise(elem, animations) { let ret = null; let p = currentPromise; for(const anim of animations) { p = p.then(function(val) { ret = val; return anim(elem); }) } return p.catch(function(e) { /* ignore and keep going */ }).then(function() { return ret; }); }
已经使用promises,代码从直接回调样式得到了很大改进,其中这种循环和异常处理是 有挑战性的。
Task.js和类似的库提供了一种使用生成器的方法 进一步简化代码保持相同的含义:
function chainAnimationsGenerator(elem, animations) { return spawn(function*() { let ret = null; try { for(const anim of animations) { ret = yield anim(elem); } } catch(e) { /* ignore and keep going */ } return ret; }); }
这是一项显着的改进。除了代码的语义内容之外的所有承诺样板都被删除了 内部函数的主体表示用户意图。但是,有 一个样板的外层,用于将代码包装在一个附加的中 生成器函数并将其传递给库以转换为promise。 需要在使用它的每个函数中重复该层 产生承诺的机制。这在典型的异步中很常见 Javascript代码,有消除需要的价值 剩下的样板。
使用异步功能,删除所有剩余的样板, 只留下程序文本中具有语义意义的代码:
async function chainAnimationsAsync(elem, animations) { let ret = null; try { for(const anim of animations) { ret = await anim(elem); } } catch(e) { /* ignore and keep going */ } return ret; }
来自Jake Archibald的文章ES7 async functions:
与promises异步
在HTML5Rocks article on promises中,最后的例子展示了如何 你为故事加载了一些JSON数据,然后用它来获取更多 章节的JSON数据,然后尽快按顺序呈现章节 他们到了。
代码如下所示:
function loadStory() { return getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); return story.chapterURLs.map(getJSON) .reduce(function(chain, chapterPromise) { return chain.then(function() { return chapterPromise; }).then(function(chapter) { addHtmlToPage(chapter.html); }); }, Promise.resolve()); }).then(function() { addTextToPage("All done"); }).catch(function(err) { addTextToPage("Argh, broken: " + err.message); }).then(function() { document.querySelector('.spinner').style.display = 'none'; }); }
不错,但是......
这次使用ES7异步功能...
async function loadStory() { try { let story = await getJSON('story.json'); addHtmlToPage(story.heading); for (let chapter of story.chapterURLs.map(getJSON)) { addHtmlToPage((await chapter).html); } addTextToPage("All done"); } catch (err) { addTextToPage("Argh, broken: " + err.message); } document.querySelector('.spinner').style.display = 'none'; }
使用异步函数(full proposal),您可以
await
承诺。 这会以非阻塞方式停止该功能,等待承诺 解决&返回值。如果承诺拒绝,它会抛出 拒绝价值,因此您可以使用catch
处理它。修改:我最初在箭头函数apparently that's not allowed中使用了
await
,因此我用for
替换了它 环。 Domenic给了我一个关于whyawait
can't be used in arrow functions的知识。
loadStory
会返回一个承诺,因此您可以在其他异步中使用它 功能(async function() { await loadStory(); console.log("Yey, story successfully loaded!"); }());
来自KoaJS文章The Evolution of Asynchronous JavaScript:
发电机/产量
JavaScript Generators是一个相对较新的概念,他们是 在ES6中引入(也称为ES2015)。
不是很好,当你执行你的功能时,你可以随时暂停它,计算其他东西,做其他事情,以及 然后返回它,即使有一些价值并继续?
这正是发电机功能为您所做的。当我们打电话给 生成器功能它没有开始运行,我们将不得不迭代 通过它手动。
function* foo () { var index = 0; while (index < 2) { yield index++; } } var bar = foo(); console.log(bar.next()); // { value: 0, done: false } console.log(bar.next()); // { value: 1, done: false } console.log(bar.next()); // { value: undefined, done: true }
如果要轻松使用生成器来编写异步 JavaScript,您还需要co。
Co是Node.js和浏览器的基于生成器的控制流优度,使用promises,让你在一个非阻塞代码中编写 很好的方式。
使用
co
,我们之前的示例可能如下所示:co(function* (){ yield Something.save(); }).then(function() { // success }) .catch(function(err) { //error handling });
您可能会问:并行运行的操作如何?答案是 比你想象的更简单(在引擎盖下它只是一个
Promise.all
的):yield [Something.save(), Otherthing.save()];
Async / await
异步功能在ES7中引入 - 目前仅可用 使用像babel这样的转换器。 (免责声明:现在我们正在讨论 async关键字,而不是异步包)
简而言之,使用
async
关键字,我们可以完成我们正在做的事情co
和生成器的组合 - 除了黑客攻击。在使用Promises的引擎
async
函数下 - 这就是为什么 异步函数将返回Promise
。