javascript – 如何交错/合并异步迭代?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 如何交错/合并异步迭代?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2139字,纯文字阅读大概需要4分钟。
内容图文
![javascript – 如何交错/合并异步迭代?](/upload/InfoBanner/zyjiaocheng/699/a8f311338d6b403e8dd59af1012cd954.jpg)
假设我有一些像这样的asnyc可迭代对象:
// Promisified sleep function
const sleep = ms => new Promise((resolve, reject) => {
setTimeout(() => resolve(ms), ms);
});
const a = {
[Symbol.asyncIterator]: async function * () {
yield 'a';
await sleep(1000);
yield 'b';
await sleep(2000);
yield 'c';
},
};
const b = {
[Symbol.asyncIterator]: async function * () {
await sleep(6000);
yield 'i';
yield 'j';
await sleep(2000);
yield 'k';
},
};
const c = {
[Symbol.asyncIterator]: async function * () {
yield 'x';
await sleep(2000);
yield 'y';
await sleep(8000);
yield 'z';
await sleep(10000);
throw new Error('You have gone too far! ');
},
};
现在,假设我可以像这样连接它们:
const abcs = async function * () {
yield * a;
yield * b;
yield * c;
};
产生的(前9个)项目将是:
(async () => {
const limit = 9;
let i = 0;
const xs = [];
for await (const x of abcs()) {
xs.push(x);
i++;
if (i === limit) {
break;
}
}
console.log(xs);
})().catch(error => console.error(error));
// [ 'a', 'b', 'c', 'i', 'j', 'k', 'x', 'y', 'z' ]
但是想象一下,我不关心顺序,a,b和c以不同的速度屈服,并且我想尽可能快地屈服.
我怎样才能重写这个循环,以便尽快产生xs,忽略顺序?
a,b或c也可能是无限序列,因此解决方案不能要求将所有元素缓冲到数组中.
解决方法:
没有办法用循环语句写这个. async / await代码总是按顺序执行,要同时执行操作,需要直接使用promise combinators.对于普通的承诺,有Promise.all,对于异步迭代器,什么都没有(还),所以我们需要自己编写它:
async function* combine(iterable) {
const asyncIterators = Array.from(iterable, o => o[Symbol.asyncIterator]());
const results = [];
let count = asyncIterators.length;
const never = new Promise(() => {});
function getNext(asyncIterator, index) {
return asyncIterator.next().then(result => ({
index,
result,
}));
}
const nextPromises = asyncIterators.map(getNext);
while (count) {
const {index, result} = await Promise.race(nextPromises);
if (result.done) {
nextPromises[index] = never;
results[index] = result.value;
count--;
} else {
nextPromises[index] = getNext(asyncIterators[index], index);
yield result.value;
}
}
return results;
}
请注意,combine不支持将值传递到next或通过.throw或.return取消.
你可以这样称呼它
(async () => {
for await (const x of combine([a, b, c])) {
console.log(x);
}
})().catch(console.error);
内容总结
以上是互联网集市为您收集整理的javascript – 如何交错/合并异步迭代?全部内容,希望文章能够帮你解决javascript – 如何交错/合并异步迭代?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。