[英]for..in loop for asynchronous tasks in Javascript
我有一个关联容器(键/值,“哈希”)。 我使用for..in循环遍历它:
for (key in container) {
doSomethingWith(key, container[key]
}
现在,我希望doSomethingWith()返回一个promise(Q或标准的诺言),并且我想顺序地而不是并行地进行迭代。 也就是说,我希望每次调用doSomethingWith()都可以在再次调用之前解决其诺言。
我该怎么做?
有没有一种方法可以遍历键而不求助于Object.keys()(在我的情况下这很长)和索引? 新的Map类有帮助吗?
它可能已经有人写过了。 另外,如果我想限制并发性(例如,按照make -j 10的精神,正在进行10个somethingWith()),则复杂性会激增,因此成熟的实现必须存在于某处。
我如何精确地链接它? 我的想法是使用一个辅助函数,该函数从done()调用自身:
function forEachKey(obj, doSomething) {
const q = Q.defer()
const keys = Object.keys(obj)
const idx = 0
const helper = () =>
if (idx < keys.length) {
doSomething(idx).done(helper)
idx += 1
}
else
{
q.resolve()
}
}
您需要做出一连串的承诺。 这是带有reduce的示例:
Object.keys(obj).reduce((promiseSoFar, key) =>
promiseSoFar.then(() => doSomethingWith(key, container[key])
, Promise.resolve());
有没有一种方法可以遍历键而不求助于Object.keys()(在我的情况下这很长)和索引
我不确定对Object.keys的厌恶是什么,但是是的,您可以在没有Object.keys的情况下构建承诺链
let promiseSoFar = Promise.resolve();
for (let key in container) {
promiseSoFar = promiseSoFar.then(() => doSomethingWith(key, container[key]));
}
它是一个非常简单的演示,但是我认为这说明了如何使用异步/等待来实现所需的功能。
const container = { name: "test", value: "test2" }; const doSomethingWith = (x, y) => new Promise((resolve, reject) => { console.log(x); resolve(x); }); (async() => { for (let key in container) { await doSomethingWith(key, container[key]); } })();
当我在节点4.9.1上时,我无法使用异步/等待。 所以这是我自己使用yield
:
function* keyGenerator(obj)
{
for (const key in obj)
{
yield key
}
}
exports.asyncForIn = function (obj, doSomething)
{
const keyGen = keyGenerator(obj)
const q = Q.defer()
const rec = () => {
const i = keyGen.next()
if (!i.done)
{
doSomething(i.value).done(rec, (x) => q.reject(x))
}
else
{
q.resolve()
}
}
rec()
return q.promise
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.