node async library:使用回调转换promise结构

时间:2018-02-09 17:27:45

标签: javascript node.js asynchronous

我得到了以下代码块:

new Promise((res, rej) => {
  if (checkCondition()) {
    res(getValue())
  } else {
    getValueAsync((result) => {
      res(result)
    })
  }
}).then((value) => {
  doStuff(value)
})

我想使用async库,这是代码库的其余部分所使用的。我试图弄清楚哪个函数最能解决这个问题。我只想出一个解决方案,但看起来有点笨重:

async.tryEach([
  (cb) => {
    if (checkCondition()) {
      cb (null, getValue())
    } else {
      cb (1)
    }
  },
  (cb) => {
    if (!checkCondition()) {
      getValueAsync((result) => {
        cb(null, result)
      })
    } else {
      cb (1)
    }
  }],
  (err, value) => {
    doStuff(value)
  }
)
像我说的那样,这感觉很笨拙。很不错,它以异步方式运行检查,我很确定它总会得到正确的结果,但代码块现在更大,更混乱。

我唯一的目的是使用与代码库的其余部分相同的库和技术,它们根本不使用promises。我无法在任何地方找到类似的控制流程块,这就是我需要自己构建它的原因。如果我坚持承诺,那就这样吧,但我想找到一个使用该库的解决方案。

1 个答案:

答案 0 :(得分:1)

我认为你可能会过度思考这个问题。

异步库适用于Node.js样式的异步代码。每the docs

  

所有这些函数假设您遵循Node.js约定,即提供单个回调作为异步函数的最后一个参数 - 一个期望将Error作为其第一个参数的回调 - 并调用一次回调。

因此,您的承诺代码的异步样式版本如下所示:

function myThing(cb) {
  if (checkCondition()) {
    cb(null, getValue());
  } else {
    getValueAsync(result => cb(null, result));
  }
}

myThing((err, res) => doStuff(res));

你会注意到这看起来很像你的原始承诺代码。

由于myThing接受Node.js样式的回调函数作为其最后一个参数,现在可以将它与任何异步库的函数一起使用,例如:

async.series(
  [ myThing, myThing, myThing ],
  (err, res) => doStuff(res)
);

您可以在下面的代码段中看到一个工作示例。

const condition = false;
const checkCondition = () => condition;
const getValue = () => 123;
const getValueAsync = cb => setTimeout(() => cb(getValue()), 250);
const doStuff = value => console.log('doStuff', value);

function myThing(cb) {
  if (checkCondition()) {
    cb(null, getValue());
  } else {
    getValueAsync(result => cb(null, result));
  }
}

myThing((err, res) => doStuff(res));

async.series(
  [ myThing, myThing, myThing ],
  (err, res) => doStuff(res)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.0/async.min.js"></script>