首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ES6异步发电机结果

ES6异步发电机结果
EN

Stack Overflow用户
提问于 2016-01-09 12:57:30
回答 2查看 433关注 0票数 5

ES6有返回迭代器的生成器

代码语言:javascript
复制
function* range(n) {
    for (let i = 0; i < n; ++i) {
        yield i;
    }
}

for (let x of range(10)) {
    console.log(x);
}

有一个关于返回应许的异步函数的建议

代码语言:javascript
复制
async function f(x) {
    let y = await g(x);
    return y * y;
}

f(2).then(y => {
    console.log(y);
});

如果我把这两者结合在一起,会发生什么?

代码语言:javascript
复制
async function* ag(n) {
    for (let i = 0; i < n; ++i) {
         yield i;
    }
}

它还能返回什么?是Promise<Iterator<Item>>吗?Iterator<Promise<Item>>?还有别的吗?我怎么消费它?我认为应该有一个相应的for循环,它将异步地迭代其结果,如下所示:

代码语言:javascript
复制
for (await let x of ag(10)) {
    console.log(x);
}

它在尝试访问下一个项目之前等待每个项目可用。

EN

回答 2

Stack Overflow用户

发布于 2022-08-23 03:59:15

自从写了这篇文章以来,很多东西都变了。Promisesiterators/generatorsasync/await语法都是标准的一部分。让我们看看在不同方法上运行简单异步操作(例如setTimeout)的过程。

让我们考虑setTimeout函数的一个简单的承诺包装器。然后,我们可以实现一个简单的承诺链到console.log消息的睡眠延迟。

代码语言:javascript
复制
function sleep(delay) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, delay);
    } );
}

console.log('one');
sleep(1000)
.then( function () {
    console.log('two');
    return sleep(1000);
} )
.then( function () {
    console.log('three');
} );

现在,让我们考虑使用异步/等待语法重写上面的承诺链:

代码语言:javascript
复制
function sleep(delay) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, delay);
    } );
}

(async function () {
    console.log('one');
    await sleep(1000);
    console.log('two');
    await sleep(1000);
    console.log('three');
})();

非常好。在新标准之前,人们使用https://babeljs.io通过使用迭代器/生成器语法重写await/async来帮助将较新的JavaScript标准转换为早期版本:

代码语言:javascript
复制
function sleep(delay) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, delay);
    } );
}

_asyncToGenerator(function *() {
    console.log('one');
    yield sleep(1000);
    console.log('two');
    yield sleep(1000);
    console.log('three');    
})();

function _asyncToGenerator(fn) {
    return function() {
        var self = this,
        args = arguments
        return new Promise(function(resolve, reject) {
            var gen = fn.apply(self, args)
            function _next(value) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value)
            }
            function _throw(err) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err)
            }
            _next(undefined)
        })
    }
}

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
        var info = gen[key](arg)
        var value = info.value
    } catch (error) {
        reject(error)
        return
    }
    if (info.done) {
        resolve(value)
    } else {
        Promise.resolve(value).then(_next, _throw)
    }
}

票数 1
EN

Stack Overflow用户

发布于 2016-01-09 13:50:11

只是思考一下:Iterator-函数没有返回值,所以让它们异步是没有意义的。然后,这两种方法之间存在着概念上的差距。迭代器是基于拉动的:调用迭代器并调用新值的计算--承诺是基于推送的:承诺将结果推送给它的侦听器。(一次或从未)

虽然在某些情况下可以创建一个Iterator<Pomise<Item>>

代码语言:javascript
复制
function* f(g){
    for(...){
        let y = await g();
        yield y;
    }
}

我想不出在任何情况下,把一个爱尔兰人变成一个承诺是有意义的。因为从Iterator的定义实例化Iterator没有任何异步。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34693721

复制
相关文章

相似问题

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