ES6生成器:将回调转换为迭代器

Mar*_*ele 7 javascript asynchronous ecmascript-6 babeljs

我在babel的帮助下试验ES6生成器,我很难理解如何(或者如果!)我可以有效地使用基于回调的异步函数来输出迭代器.

假设我希望能够编写一个带有大量URL的函数,异步下载它们并在下载后立即返回它们.我希望能够写出如下内容:

let urls = ['http://www.google.com', 'http://www.stackoverflow.com' ];
for ( {url, data} of downloadUrls(urls) ) {
    console.log("Content of url", url, "is");
    console.log(data);
}
Run Code Online (Sandbox Code Playgroud)

我该如何实施downloadUrls?理想情况下,我希望能够写下以下内容:

var downloadUrls = function*(urls) {
    for( let url of urls ) {
        $.ajax(url).done( function(data) {
            yield data;
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

这当然不起作用,因为``yield''是在回调中调用的,而不是直接在生成器内部调用.我可以在网上找到许多尝试相同的例子,它们要么不透明,需要启用浏览器/节点标记,或者使用特定于节点的功能/库.最接近我需要的库似乎是task.js,但我无法在最新的Chrome上运行最简单的示例.

有没有办法使用标准和当前功能获得预期的行为,(目前我的意思是可以使用像babel这样的转换器,但不需要在浏览器上启用额外的标志)或者我必须等待async/await吗?

Ber*_*rgi 0

有没有办法使用标准和当前功能来获得预期的行为

是的,使用承诺和生成器。许多 Promise 库和一些独立的库都使用生成器“协程”。

但请注意,您不能将迭代与异步混合在一起,您只能将生成器用于其中任何一个。您的示例似乎让他们有点困惑 - 看起来您希望该for ( {url, data} of downloadUrls(urls) ) {循环同步工作,但这是行不通的。

我还得等吗async/await

不,你不必等待,Babel 已经支持他们了