ES6替代async.seq流量控制

时间:2017-12-21 01:27:15

标签: javascript node.js

使用NodeJS,我之前使用async.seq(允许每个传入的函数使用前一个函数的返回值)。例如,如果我有一个函数数组,我想将一个值传递给第一个,然后是第二个,直到我得到最终结果。

既然async / await和generator已经可用,我一直试图找出是否有原生解决方案,但我没有看到任何内容。

有没有办法通过一系列函数本地传递参数,或者最简单的方法仍然是使用async包。

注意,在我的特定用例中,每个函数都返回一个promise。

3 个答案:

答案 0 :(得分:1)

它不是ES6(很久以前它已经被称为ES2015),但node.js已经支持async / await。所以这与使用async.seq可以实现的类似。当然,您不需要声明中间变量,这取决于您。并且async.seq遵循此处不需要的特定约定。

async function client(input) {
    const p1 = await process1(input)
    const p2 = await process2(p1)
    const p3 = await process3(p2)
    const p4 = await process4(p3)
    return p4
}

答案 1 :(得分:0)

我通常在处理Promises

时使用Array.prototype.reduce
TIMESTAMP

我们从最初的Promise.resolve(initialValue)开始,并在解析前一个promise后调用当前的promise。

如果你喜欢async / await你可以用for循环来做,但我发现减少更优雅

const addOne = number => {
  console.log(number);
  return Promise.resolve(number + 1);
};

const sequence = [addOne, addOne];

sequence.reduce((previous, current) => previous.then(current), Promise.resolve(0))
  .then(finalValue => console.log(finalValue)); // 2

答案 2 :(得分:0)

我编写了一个名为compose的函数,它实现了reduce,但promises是可选的(带then的东西,所以任何承诺都像结果一样):

//not exported, checks if a value could be like promise
const promiseLike =
x =>
  (x!==undefined && typeof x.then === "function")
;
//not exported, if x is promise then fn is called with the
//  resolve of x
const ifPromise =
  (fn) =>
  (x) =>
    promiseLike(x)
      ?x.then(fn)
      :fn(x)
;
/**
* 
* takes 2 functions and turns it into:
* fn2(fn1(x)) when a value x is provided
* if x is a promse it will turn it into:
* x.then(x => fn2(fn1(x)))
* if fn1(x) is a promise it will turn it into:
* fn1(x).then(x => fn2(x))
* if both x and fn1(x) are promises:
* x.then(x => fn1(x)).then(x => fn2(x))
*/
const compose2 =
  fn1=>
  fn2=>
    x =>
      ifPromise
        (fn2)
        (
          ifPromise
            (fn1)
            (x)
        )
;

/**
turns an array of functions [fn1,fn2,fn3] into:
fn3(fn2(fn3(x)))
both x or any of the results of the functions can be a promise
If it is a promse then the next function will be called with
the resolve value of the promise.
If the promse is rejected the next function is not called
*/
const compose =
  fns =>
    fns.reduce(
      (acc,fn) => compose2(acc)(fn)
      ,x=>x//id function
    )
;

用法示例:

const searchHandler = search =>
  copose([
    x=>(showLoading(),x),
    makeSearchRequest,
    formatSearchResult,
    hideLoading
  ])(search)
  .catch(
    compose([
      showError,
      hideLoading
    ])
  )