Javascript 什么是ES7异步函数?

Javascript 什么是ES7异步函数?,javascript,async-await,ecmascript-next,Javascript,Async Await,Ecmascript Next,我已经使用巴别塔一段时间了,我很喜欢它。然而,在主页上,它列出了支持的功能,它说异步函数 (async function() { await loadStory(); console.log("Yey, story successfully loaded!"); }()); 我用谷歌搜索了很多次,我能理解的似乎就是它是ES7的一个特性 请问什么是ES7异步函数?通常被称为ES7或ECMAScript 7是ECMA-262标准(通常被称为JavaScript)的下一个发展,目前仍

我已经使用巴别塔一段时间了,我很喜欢它。然而,在主页上,它列出了支持的功能,它说异步函数

(async function() {
    await loadStory();
    console.log("Yey, story successfully loaded!");
}());
我用谷歌搜索了很多次,我能理解的似乎就是它是ES7的一个特性

请问什么是ES7异步函数?

通常被称为ES7或ECMAScript 7是ECMA-262标准(通常被称为JavaScript)的下一个发展,目前仍处于早期阶段

异步函数是一种新的JavaScript功能,作为ES2016标准的一部分提出,但尚未得到任何浏览器的支持。它们是建在屋顶上的

请参阅下面的介绍,从各种权威来源了解这一新功能

注: 尽管异步函数通常被称为ES7异步函数,例如,为了消除它们与ES7异步函数之间的歧义,建议在下一个标准的提案达到第4阶段后,才将其作为一项功能包含在下一个标准中

异步函数目前仅处于第3阶段。事实上,正如下面的评论所指出的,ES2016很可能会出现

发件人:

介绍 ECMAScript中承诺和生成器的介绍提供了一个 有机会显著改进的语言级别模型 在ECMAScript中编写异步代码

在会议期间,与会者也提出了类似的建议 ES6讨论。这里的提案支持相同的用例,使用 类似或相同的语法,但直接基于控制流 结构与发电机的结构平行,并使用 返回类型,而不是定义自定义机制

这项建议的发展正在进行中 . 请将问题归档 那里非琐碎的贡献仅限于TC39成员,但是 欢迎并鼓励对小问题的请求

本提案的现状 该提案被接纳为第三阶段的候选人 ECMAScript于2015年9月发布。冠军 计划在第4阶段接受本建议书,该阶段由 11月底

例子 以下面的示例为例,首先使用承诺编写。此代码 将一组动画链接到一个元素上,并在出现动画时停止 动画中的异常,并返回 最终成功执行动画

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;
    });
}
已经有了承诺,代码比直接回调风格有了很大的改进,直接回调风格使用了这种循环和异常处理 具有挑战性

类似的库提供了一种使用生成器的方法 为了进一步简化保持相同含义的代码:

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;
}
从作者的文章:

与承诺不同步 在中,最后一个示例演示了如何 您可以为一篇报道加载一些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';
    });
}
co(function* (){  
    yield Something.save();
}).then(function() {
    // success
})
.catch(function(err) {
    //error handling
});
不错,但是

这次使用ES7异步函数… 使用异步函数,您可以等待承诺。 这将以非阻塞方式停止函数,等待承诺 解析并返回值。如果承诺被拒绝,它就会被抛弃 拒绝值,因此可以使用catch处理它

编辑:我最初在arrow函数中使用wait,所以我将其替换为for 环多梅尼克给了我一个教训

loadStory返回一个承诺,因此您可以在其他异步应用程序中使用它 功能

(async function() {
    await loadStory();
    console.log("Yey, story successfully loaded!");
}());
第条:

发电机/产量 这是一个相对较新的概念 在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 }
您可能会问:并行运行的操作如何?答案是 比你想象的要简单,它只是一个 承诺所有人:

异步/等待 异步函数是我的 在ES7中引入-目前仅提供 使用像巴贝尔这样的运输工具。免责声明:现在我们讨论的是 async关键字,而不是async包

简言之,使用async关键字,我们可以做我们正在做的事情 co和发电机的组合——除了黑客攻击

使用承诺的幕后异步函数-这就是 异步函数将返回一个承诺

通常称为ES7或ECMAScript 7是ECMA-262标准(通常称为JavaScript)的下一个发展,目前仍处于早期阶段

异步函数是一种新的JavaScript功能,作为ES2016标准的一部分提出,但尚未得到任何浏览器的支持。它们是建在屋顶上的

请参阅下面的介绍,从各种权威来源了解这一新功能

注: 尽管异步函数通常被称为ES7异步函数,例如,为了消除它们与ES7异步函数之间的歧义,建议在下一个标准的提案达到第4阶段后,才将其作为一项功能包含在下一个标准中

异步函数目前仅处于第3阶段。事实上,正如下面的评论所指出的,ES2016很可能会出现

发件人:

介绍 ECMAScript中承诺和生成器的介绍提供了一个 有机会显著改进的语言级别模型 在ECMAScript中编写异步代码

在会议期间,与会者也提出了类似的建议 ES6讨论。这里的提案支持相同的用例,使用 类似或相同的语法,但直接基于控制流 结构与发电机的结构平行,并使用 返回类型,而不是定义自定义机制

这项建议的发展正在进行中 . 请将问题归档 那里非琐碎的贡献仅限于TC39成员,但是 欢迎并鼓励对小问题的请求

本提案的现状 该提案被接纳为第三阶段的候选人 ECMAScript于2015年9月发布。冠军 计划在第4阶段接受本建议书,该阶段由 11月底

例子 以下面的示例为例,首先使用承诺编写。此代码 将一组动画链接到一个元素上,并在出现动画时停止 动画中的异常,并返回 最终成功执行动画

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;
    });
}
已经有了承诺,代码比直接回调风格有了很大的改进,直接回调风格使用了这种循环和异常处理 具有挑战性

类似的库提供了一种使用生成器的方法 为了进一步简化保持相同含义的代码:

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;
}
从作者的文章:

与承诺不同步 在中,最后一个示例演示了如何 您可以为一篇报道加载一些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';
    });
}
co(function* (){  
    yield Something.save();
}).then(function() {
    // success
})
.catch(function(err) {
    //error handling
});
不错,但是

这次使用ES7异步函数… 使用异步函数,您可以等待承诺。 这将以非阻塞方式停止函数,等待承诺 解析并返回值。如果承诺被拒绝,它就会被抛弃 拒绝值,因此可以使用catch处理它

编辑:我最初在arrow函数中使用wait,所以我将其替换为for 环多梅尼克给了我一个教训

loadStory返回一个承诺,因此您可以在其他异步应用程序中使用它 功能

(async function() {
    await loadStory();
    console.log("Yey, story successfully loaded!");
}());
第条:

发电机/产量 这是一个相对较新的概念 在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 }
您可能会问:并行运行的操作如何?答案是 比你想象的要简单 k在兜帽下它只是一个 承诺所有人:

异步/等待 ES7中引入了异步函数,目前仅可用 使用像巴贝尔这样的运输工具。免责声明:现在我们讨论的是 async关键字,而不是async包

简言之,使用async关键字,我们可以做我们正在做的事情 co和发电机的组合——除了黑客攻击

使用承诺的幕后异步函数-这就是 异步函数将返回一个承诺


异步等待ES6承诺的工作。您可以将其视为编写具有承诺的同步代码的一种方式

async关键字标记为将进行异步调用的方法。wait关键字标记实际呼叫

对于承诺,您需要将一个方法传递给。然后使用承诺的方法来处理结果

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);
}
这样做的好处是它简单地减少了回调的需要


有关更多信息,请参阅:

异步等待使用ES6承诺。您可以将其视为编写具有承诺的同步代码的一种方式

async关键字标记为将进行异步调用的方法。wait关键字标记实际呼叫

对于承诺,您需要将一个方法传递给。然后使用承诺的方法来处理结果

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);
}
这样做的好处是它简单地减少了回调的需要


有关更多信息,请参见:

异步函数是一个可怕的想法,让您放弃承诺,逐行编写异步代码,而不必担心事情何时完成等等。@FrédéricHamidi-我当然会,但这并不意味着我认为所有的更改都是好的,在我看来,这不是ES7异步搜索► 它似乎解释了我所能看到的一切。@adeneo:async/await并没有放弃承诺。它拥抱他们。它使具有复杂控制流的promise代码更易于阅读和编写。@adeneo:,它使您能够使用各种各样的控制结构,这些控制结构具有以前难以使用的承诺。异步函数仍然是可以的,它们每个都返回一个承诺!它们可以完全透明地与普通的承诺返回函数交换,就像生成器函数可以与迭代器返回函数交换一样唯一的区别是。toString.Async函数是一个可怕的想法,让你放弃承诺,逐行编写异步代码,不必担心事情什么时候完成等等@FrédéricHamidi-我当然担心,但这并不意味着我认为所有的改变都是好的,在我看来,这不是。ES7异步搜索► 它似乎解释了我所能看到的一切。@adeneo:async/await并没有放弃承诺。它拥抱他们。它使具有复杂控制流的promise代码更易于阅读和编写。@adeneo:,它使您能够使用各种各样的控制结构,这些控制结构具有以前难以使用的承诺。异步函数仍然是可以的,它们每个都返回一个承诺!它们可以完全透明地与普通的承诺返回函数交换,就像生成器函数可以与迭代器返回函数交换一样。唯一的区别是。toString。为什么这个答案会被否决?!我的两分钱:我考虑了几分钟,最后投了反对票,因为它是来自不同来源的摘录的集合,几乎没有原创内容。我承认你在格式化方面所做的努力,但我仍然认为我们不应该鼓励你这么做。@FrédéricHamidi:说得好。时间会证明一切的!再次感谢你的回馈!仅供参考,async/await不会成为ES7 ES2016的一部分。只有第四阶段的提案是有效的。@FelixKling:谢谢!我在我的答案中添加了一条注释,以反映您在评论中提出的观点,以及涉及即将推出的Ecmascript标准命名的各种小改进。为什么这个答案会被否决?!我的两分钱:我考虑了几分钟,最后投了反对票,因为它是来自不同来源的摘录的集合,几乎没有原创内容。我承认你在格式化方面所做的努力,但我仍然认为我们不应该鼓励你这么做。@FrédéricHamidi:说得好。时间会证明一切的!再次感谢你的回馈!仅供参考,async/await不会成为ES7 ES2016的一部分。只有第四阶段的提案是有效的。@FelixKling:谢谢!我在我的回答中添加了一个注释,以反映您在评论中提出的观点,以及涉及即将到来的Ecmascript标准命名的各种小改进。请在否决投票时留下评论。如果您因为不喜欢async/await的概念而投反对票,请告诉我。仅供参考,承诺是ES6 ES2015的一部分,而async/await将不会成为ES7ES2016的一部分。感谢您的示例。我终于明白了
我意识到异步本身并不是使函数异步。这需要通过承诺来实现。async仅将某些函数标记为可以使用wait,并使对async func的函数调用显示为synchronous-ish。请在否决投票时留下评论。如果您因为不喜欢async/await的概念而投反对票,请告诉我。仅供参考,承诺是ES6 ES2015的一部分,而async/await将不会成为ES7ES2016的一部分。感谢您的示例。我终于意识到,异步本身并不能使函数异步。这需要通过承诺来实现。async仅将某些函数标记为可以使用Wait,并使对async func的函数调用看起来是同步的。