我有一个关联容器(键/值,“哈希”)。我使用for..in循环遍历它:
for (key in container) {
doSomethingWith(key, container[key]
}
现在,我希望doSomethingWith()返回一个Promise(Q或标准的Promise),我想顺序地而不是并行地进行迭代。也就是说,我希望每次调用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()
}
}
答案 0 :(得分:1)
您需要做出一连串的承诺。这是带有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]));
}
答案 1 :(得分:1)
这是一个非常简单的演示,但是我认为这表明如何使用异步/等待来实现您的需求。
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]);
}
})();
答案 2 :(得分:1)
当我在节点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
}