在“功能上”累积承诺值

时间:2017-04-17 07:04:36

标签: javascript node.js es6-promise

说我有这个:

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));

}

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

const acc = {}; // accumulated value

并以某种方式从promise链中返回?

最终,acc变量是从承诺链中解析出来的,但是想知道我是否可以以某种方式避免在链外“声明”它。

编辑:类似这样的种子数据如下:

  {
    '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 foo(one,two,three){


}

我想注入这3个依赖项。它们可以“并行”获取,但在threeone获得之前,two将被屏蔽。

什么是subDeps变量?如果key =“3”,则subDeps['one','two']

2 个答案:

答案 0 :(得分:1)

你可以将第二个参数的数组传递给.reduce(),在.reduce()回调中使用破坏赋值来获取Promise并传递对象

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 */)

答案 1 :(得分:1)

我想知道可以并行加载任何子节点的subDeps的整个列表。在更深入地看待问题时,我认为没有理由不这样做。事实上,我能看到的唯一潜在问题是某些值高于但不低于此点可能是一个承诺,因此,您甚至可以从这个特定的递归函数中获取承诺。 ..

但是...

这就是我所看到的合理的重构。让我知道是否缺少一些明显的需求。

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,我还没有闭上眼睛)。 / p>