对NodeJS的承诺

时间:2018-11-22 13:37:34

标签: node.js promise

我想将Promise与NodeJS一起使用,但似乎无法按预期工作。

我想按此顺序查看所有文件的LOG 1LOG 2LOG 3LOG 4被隐藏了...

但是我明白了:

LOG 1
LOG 3
LOG 1
LOG 3
LOG 1
LOG 3
SUCCESS LOG 2
SUCCESS LOG 2
SUCCESS LOG 2
SUCCESS LOG 2

我的代码:

var filePromise = _.map(files, function(file) {

var filePath = './sql/' + file;

fs.lstat(filePath, function(err, stats) {

  if (stats.isFile() && file !== '.gitignore' && file !== 'index.js') {

    fs.readFile(filePath, 'utf-8', function(err, data) {

      console.log('LOG 1');

      db.query(data).then(function() {
        console.log(colors.green('SUCCESS LOG 2'));
      }).catch(function() {
        console.log(colors.red('ERROR LOG 2'));
      });

      console.log('LOG 3');

    });
  }
});
});

Promise.all(filePromise).then(function() {
  console.log(colors.green('LOG 4'));
});

1 个答案:

答案 0 :(得分:1)

为了使filePromise包含一个Promise集合,您需要为map调用的每次迭代返回一个Promise。只有这样,才能正确评估对Promise.all的呼叫。

var filePromise = _.map(files, function(file) {
    return new Promise(function(resolve, reject) {
        var filePath = './sql/' + file;

        fs.lstat(filePath, function(err, stats) {

            if (stats.isFile() && file !== '.gitignore' && file !== 'index.js') {

                fs.readFile(filePath, 'utf-8', function(err, data) {

                    console.log('LOG 1');

                    db.query(data).then(function() {
                        console.log(colors.green('SUCCESS LOG 2'));
                        resolve();
                    }).catch(function() {
                        console.log(colors.red('ERROR LOG 2'));
                        reject();
                    });

                    console.log('LOG 3');

                });
            } else {
                reject(new Error("failed condition"))
            }
        });
    })
});

Promise.all(filePromise).then(function() {
    console.log(colors.green('LOG 4'));
});

这不能解决控制台日志的顺序。那是一个单独的问题。您的控制台日志实际上并没有出现故障,它们正在按预期方式进行日志记录。但是,这是由于您正在对db.query进行异步调用而引起的,该调用在被触发时不会阻止等待响应。而是在函数调用返回后立即执行下一行。

旁注::请确保处理传递给errfs.lstat的内联回调函数的fs.readFile参数。否则,将导致承诺在出现错误时永远无法完成。