收集承诺价值“function上”

说我有这个:

function getAllPromises(key: string, val: any): Promise { const subDeps = someHash[key]; const acc = {}; // accumulated value return subDeps.reduce(function (p, k) { return p.then(v => getAllPromises(k, v)).then(function (v) { acc[k] = v; return acc; }); }, Promise.resolve(val)); } 

有没有办法避免必须声明一个单独的variables:

 const acc = {}; // accumulated value 

并以某种方式从承诺链返回呢?

最终,accvariables是从promise链得到的结果,但是我想知道如果我能够以某种方式避免在链外面声明它。

编辑:像这样的种子数据如下所示:

  { 'one': [function (v) { return Promise.resolve('one'); }], 'two': ['one', function (v) { return Promise.resolve('two'); }], 'three': ['one', 'two', function (v) { return Promise.resolve('three'); }], } 

这只是一个声明依赖树。 依赖可以并行解决。 但在运行时可能会有效阻止。 例如,如果我有这样的function:

 function foo(one,two,three){ } 

我想注入这3个依赖项。 他们可以“并行”来源,但three将被阻止,直到onetwo采购。

什么是subDepsvariables? 在key =“three”的情况下, subDeps['one','two']

在这里,我要走出一条边,认为任何子节点的subDeps的整个列表可以并行加载。 在深入探讨这个问题时,我认为没有理由不这样做。 事实上,我所看到的唯一的潜在问题是,有些价值高于但不低于这一点可能是一个承诺,因此,你甚至可以从这个特定的recursion函数中得到承诺…

但…

这是我所看到的一个合理的重构。 让我知道如果这是缺less一些明显的需要。

 const appendKeyValue = (dict, [key, value]) => { dict[key] = value; return dict; }; const getKeyValuePair = hash => key => getRefactoredPromises(hash, hash[key]) .then(value => [key, value]); const getRefactoredPromises = (someHash, subDeps) => { return Promise.all(subDeps.map(getKeyValuePair(someHash))) .then(pairs => pairs.reduce(appendKeyValue, {})); }; 

事实上,如果我对这个重构是正确的,那么你甚至不需要那里的承诺。 它只是变成:

 const appendKeyValue = (dict, [key, value]) => { dict[key] = value; return dict; }; const getKeyValuePair = hash => key => [key, getRefactoredHash(hash, hash[key])]; const getRefactoredHash = (someHash, subDeps) => subDeps.map(getKeyValuePair(someHash)) .reduce(appendKeyValue, {}); 

如果这个调用的根级恰好是一个承诺,那么在这一点上这应该是无关紧要的,除非我错过了一些东西(现在是6点20分,而我还没有闭上眼睛)。

你可以在第二个parameter passing一个数组到.reduce() ,在.reduce()callback中使用破坏赋值来获得Promise和object的传递

 return subDeps.reduce(([p, acc], k) => [p.then(v => getAllPromises(k, v)).then(v => Object.assign(acc, {[k]:v})) , acc]; }, [Promise.resolve(val), {}]).shift()//.then(result => /* result : acc */)