什么是ES7异步功能?

时间:2016-02-23 14:25:01

标签: javascript async-await ecmascript-next

我一直在使用Babel一段时间,我很喜欢它。但是,在主页上列出了支持的功能,它显示Async functions

我做了很多谷歌搜索,而我似乎只能理解它是一个ES7功能。

请问什么是ES7异步功能?

2 个答案:

答案 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.jsasynchronous JavaScript消除歧义),Axel Rauschmayer建议使用not calling them that但是,作为一项功能,只有在其提案达到第4阶段时才会包含在下一个标准中。

异步功能现在只在第3阶段。事实上,ES2016可能not contain async functions(正如Felix Kling在下面的评论中指出的那样。)

来自the stage 3 proposal

  

简介

     

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给了我一个关于why await 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和生成器的组合 - 除了黑客攻击。

     

enter image description here

     

在使用Promises的引擎async函数下 - 这就是为什么   异步函数将返回Promise