azl397985856 / fe-interview

宇宙最强的前端面试指南 (https://lucifer.ren/fe-interview)
Apache License 2.0
2.84k stars 260 forks source link

【每日一题】- 2019-08-29 - 如何实现一个异步的 reduce? #25

Closed azl397985856 closed 4 years ago

azl397985856 commented 5 years ago

Array.prototype.reduce是一个同步的方法,允许我们同步地进行操作。

如果我要实现异步reduce呢?

请实现以下函数:

// 结果一个Promise数组,然后返回一个Promise
function reduceAsync(promises, initial) {
    // TODO
}
yjua commented 5 years ago
function reduceAsync(promises,initValue) {
    return promises.reduce(function(promise,currentPromise){
        return promise.then(currentPromise)
    },Promise.resolve(initValue))
}
azl397985856 commented 4 years ago

Let's take a step back - How about reduce?

Pretty straightforward, right?

function reduce(fn, initial = list[0], list) {
  let acc = initial;
  for (i in list) {
    const item = list[i];
    acc = fn(acc, item, i, list);
  }
  return acc;
}

reduce((acc, cur) => ((acc[cur] = cur), acc), {}, [1, 2, 3]);

ReduceAsync - using then to take out of the data

Cause you can't create a promise and then immediately use its result synchronously in your code, you should call .then() on the promise, and the result will be there when the promise has been resolved.

The Code is a carbon copy of the reduce listed above

function reduceAsync(fn, initial, promises) {
  let accp = initial;
  for (i in promises) {
    const promise = promises[i];
    accp = accp.then(acc => promise.then(v => fn(acc, v, i, promises)));
  }
  return accp;
}

reduceAsync((acc, cur) => ((acc[cur] = cur), acc), Promise.resolve({}), [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.resolve(3)
]).then(console.log);

Hope that make sense for U Guys~