收集承诺价值“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
将被阻止,直到one
和two
采购。
什么是subDeps
variables? 在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 */)