【问题标题】:How to write an asynchronous program with nodejs?如何用nodejs编写异步程序?
【发布时间】:2017-01-19 12:53:19
【问题描述】:

假设,例如,我想编写一个 nodejs 程序,其中我在不同的位置有两个或三个独立的部分,如 fs.readdir、fs.copy 等,但结果所有三个操作都将发送到像这样的 json 文件:

var fs = require('fs-extra');

var jsd = {
    "act1" : false,
    "act2" : false,
    "act3" : false
}

fs.readdir(path1, function (err, files) {
    if (err)  jsd.act1 = err;
    for (x in files)  console.log(files[x]);
    jsd.act1 = true;
});

fs.copy(path2, path3, function (err) {
    if (err)  jsd.act2 = err;
    jsd.act2 = true;
});

fs.remove(path4, function (err) {
    if (err)  jsd.act3 = err;
    jsd.act3 = true;
});

// all three of the above actions are independent, so it makes sense that all of them are executed asynchronously.
// Now we write jsd object to a json file; jsd's contents are dependent on the above actions though

fs.writeJson("./data.json", jsd, function (err, files) {
    if (err)   return console.error(err);
});

如何确保将正确的数据输入到文件 data.json 中,即 fs.writeJson 在之前的操作先执行后执行?

我知道一种方法是将它们全部嵌套,即

readdir() {
  copy() {
    remove() {
      writeJson();
    }
  }
}

但这可能会导致回调地狱,那么有没有更好的方法来做到这一点?

【问题讨论】:

  • 您必须以异步方式执行此操作吗?这并不意味着你在并行做事。您可以使用这些 fs 函数的同步版本并使其更简单。
  • 承诺。你研究过承诺吗?
  • 是的,我知道这些的同步版本,但是我不会使用这些的异步属性,因为节点是众所周知的
  • Promise.all 将帮助您实现这一目标
  • 您可以使用 async.parallel,但正如我所说,我在这里看不到异步方式的任何好处。

标签: node.js asynchronous callback


【解决方案1】:

您可以使用 Promise 或模块异步, 如果使用 Promise,首先必须将所有回调函数转换为 Promise,如下所示:

const reddir = function(path) {
  return new Promise((resolve, reject) => {
    fs.readdir(path, (err, files) => {
      if (err) return reject(err);
      for (x in files)  console.log(files[x]);
      resolve(true);
    });
  })  
}

那么你可以使用

Promise.all([reddir(path1), copy(path2, path3), remove(path4)])
  .spread((act1, act2, act3) => { //.spread is bluebird feature
    return writeJson(./data.json);
  })
  .catch(e => {
    // all error can handled in this
  })

如果你使用异步模块,你可以这样写:

async.parallel({
  act1: function(cb){
    fs.reddir(path1, (err, files) => {
      if (err) return cb(err);
      for (x in files)  console.log(files[x]);
      cb(true);
    })
  },
  act2: ...
},(err, jsd) => { // jsd will be {act1: true, act2: ...}
  if (err) return console.error(err); // handle all above error here;
  fs.writeJson("./data.json", jsd, function (err, files) {
    if (err)   return console.error(err);
  });
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 2011-09-02
    • 2021-12-19
    相关资源
    最近更新 更多