如何一个接一个地触发异步进程

时间:2017-08-01 21:15:04

标签: javascript node.js async.js

我应该如何修改以下代码,以便确保在Process2.update或Process2.create完成后触发Process3?

以下代码的主要目的是我想使得进程1完成。然后检查id是否存在,如果是,则触发Process2.update。如果没有,则触发Process2.create。

一旦Process2完成,检查是否存在cmd。如果是,则触发Process3。

  run: function (req, res) {
    if (req.session) {
      const values = req.params.all();
      const id = values.id;
      const cmd = values.cmd;
      const param = _.omit(values, ['cmd', 'id']);

      const cb1 = (e, d) => {
        if (e) {
          console.log(e);
          res.status(400).send({ e });
        } else {
          Process1(values);
          res.status(200).send({ d });
        }
      };
      const cd2 = (id, param, cb1) => {
        if (id) {
            Process2.update({ id }, param, cb1);
        } else {
            Process2.create(param, cb1);
        }
      };

      if (cmd) {
        cd2(id, param, cb1, Process3(values, cmd));
      }
      else {
        cd2(id, param, cb1);
      }

    } else {
      res.status(403).send({ e: 'Forbidden access.' });
    }
  }

尝试通过以下方式尝试,但不确定如何将参数id,params传递给Process2和process3

let async = require('async');
const Process1 = (value, cb) => {
    console.log("Process1()");
    console.log(value);
    cb(null, value + 1);
};
const Process2 = (value, cb) => {
    console.log("value(): wait 5 sec");
    console.log(value);
    cb(null, value+10);
};
const Process3 = (value, cb) => {
    console.log(value);
    console.log("Process3(): wait 5 sec");
    cb(null, value+100);
};
let Pro_1_2 = async.compose(Process2, Process1);
let Pro_2_3 = async.compose(Process3, Process2);
Pro_1_2(1, (e, r) => {
    Pro_2_3(r, (error, result) => {
        console.log(result);
    });
});

2 个答案:

答案 0 :(得分:0)

您是否考虑过使用async.js中的“compose”?

const a = (data, cb) => {
  var result = 'a';
  cb(null, result);
};
const b = (data, id, cb) => {
  var result = 'b';
  cb(null, result);
};
const c = (data, cb) => {
  // stuff to do with result
};

var aThenC = async.compose(c, a);
var bThenC = async.compose(c, b);

if (useA) {
  aThenC(data, (result) => {
    // result from c
    res.status(200).send(result);
  });
} else {
  bThenC(data, id, (result) => {
    // result from c
    res.status(200).send(result);
  });
}

在这种情况下, a b 分别是您的Process2创建和更新, c 是Process3的回调,如果我理解正确。

编辑:您只需在编写的功能上输入初始参数(例如注册ID)。真正构成的是:a(b(c(param)))。该参数基本上是您启动该过程所需的一切。以下函数的参数将在此之前的函数内设置。

我会在键盘上添加代码以支持它。

答案 1 :(得分:0)

您在原始问题中发布的代码似乎非常扭曲,所以我不会尝试重写它,但一般来说,如果您想执行相互依赖的异步调用,{{3}是一个很好的方式去。不是通过某些函数调用来声明尝试变异的顶部变量,而是使Process1Process2Process3异步函数更好地调用它们的回调函数新的values对象。类似的东西:

async.auto({

  doProcess1: function(cb) {
    // Assuming Process1 calls `cb(undefined, newValues)` when done.
    Process1(values, cb);
    return;
  },

  doProcess2: ['doProcess1', function(results, cb) {
    if (results.doProcess1.id) {
      Process2.update({id: results.doProcess1.id}, cb);
      return;
    } else {
      Process2.create(_.omit(results.doProcess1, ['cmd', 'id']), cb); 
      return;
    }
  }],

  doProcess3: ['doProcess2', function(results, cb) {
    if (results.doProcess2.cmd) { 
      Process3(results.doProcess2, cb);
      return;
    }
    else {
      cb(undefined, results.process2);
      return;
    }

  }]

}, function afterProcess3(err, results) {
  // Handler err or process final results.
});

注意所有return次来电。它们并非绝对必要,但是在调用异步函数后避免意外运行更多代码的良好做法。