ES6有返回迭代器的生成器
function* range(n) {
for (let i = 0; i < n; ++i) {
yield i;
}
}
for (let x of range(10)) {
console.log(x);
}有一个关于返回应许的异步函数的建议
async function f(x) {
let y = await g(x);
return y * y;
}
f(2).then(y => {
console.log(y);
});如果我把这两者结合在一起,会发生什么?
async function* ag(n) {
for (let i = 0; i < n; ++i) {
yield i;
}
}它还能返回什么?是Promise<Iterator<Item>>吗?Iterator<Promise<Item>>?还有别的吗?我怎么消费它?我认为应该有一个相应的for循环,它将异步地迭代其结果,如下所示:
for (await let x of ag(10)) {
console.log(x);
}它在尝试访问下一个项目之前等待每个项目可用。
发布于 2022-08-23 03:59:15
自从写了这篇文章以来,很多东西都变了。Promises、iterators/generators和async/await语法都是标准的一部分。让我们看看在不同方法上运行简单异步操作(例如setTimeout)的过程。
让我们考虑setTimeout函数的一个简单的承诺包装器。然后,我们可以实现一个简单的承诺链到console.log消息的睡眠延迟。
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');
} );
现在,让我们考虑使用异步/等待语法重写上面的承诺链:
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标准转换为早期版本:
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)
}
}
发布于 2016-01-09 13:50:11
只是思考一下:Iterator-函数没有返回值,所以让它们异步是没有意义的。然后,这两种方法之间存在着概念上的差距。迭代器是基于拉动的:调用迭代器并调用新值的计算--承诺是基于推送的:承诺将结果推送给它的侦听器。(一次或从未)
虽然在某些情况下可以创建一个Iterator<Pomise<Item>>
function* f(g){
for(...){
let y = await g();
yield y;
}
}我想不出在任何情况下,把一个爱尔兰人变成一个承诺是有意义的。因为从Iterator的定义实例化Iterator没有任何异步。
https://stackoverflow.com/questions/34693721
复制相似问题