使用nodejs未按正确顺序执行的指令

Instructions not executed into the right order with nodejs

我是 nodejs 的新手,正在尝试在编码时即时 cat 多个 css 文件。 chokidar 包允许我在修改文件时调用函数,但是我在执行时遇到问题。

var goconcat =
  fs.readdir(paths, function (err, files) {
      if (err) {console.log(err);}
      fs.unlink(paths + 'concat.css', function (err) {
        if (err) throw err;
        var list = files.map(function (files) {
            return path.join(paths, files);
        });
        concat(list, paths + 'concat.css',  function(err) {
          if (err) throw err
        });
      });
});

我想先删除之前的文件,然后读取目录再写一个新的"concat.css"。但是我有一个错误;

Error: ENOENT: no such file or directory, open 'public/css/concat.css'
at error (native)

似乎函数 concat() 是在目录更新之前执行的,而不是之后执行的,因此它试图对刚刚删除的文件进行 cat。为什么?

我知道nodejs是以同步的方式执行函数,但我找不到解决这个问题的方法。我尝试了 async 但我无法在两个函数之间声明一个变量,而且我无法让它工作。

如果它不能存在于回调中,使用 setTimeout(fn, 0) 技巧可能有助于确保它在变量赋值后执行。

var goconcat =
  fs.readdir(paths, function (err, files) {
      if (err) {console.log(err);}
      fs.unlink(paths + 'concat.css', function (err) {
        if (err) throw err;
        var list = files.map(function (files) {
            return path.join(paths, files);
        }); 
        setTimeout(function() {
          concat(list, paths + 'concat.css',  function(err) {
            if (err) throw err
        })}, 0);
      });
});

您遇到的问题是在通过调用 unlink 删除文件之前调用了您的 concat 函数。您可以通过嵌套回调来防止这种情况;但是,如果您使用像 async 这样的模块,并且避免自己处理 Callback Hell.

,您可能会有更好的 control flow

下面是有关如何使用 async 模块的示例。

var fs = require('fs');
var async = require('async');

var myDir = __dirname + '/data';

async.waterfall([function(callback) {
    fs.readdir(myDir, 'utf-8', function(error, files) {
        if (error) {
            return callback(error);
        }

        return callback(null, files);
    });
}, function(files, callback) {
    fs.open(myDir + '/myFile', 'wx', function(error, f) {
        if (error && error.code === 'EEXIST') {
            return callback(null, 'EEXIST');
        }

        return callback(null, 'CREATE');
    });
}, function(fileStatus, callback) {
    if (fileStatus === 'EEXIST') {
        console.log('File exists. Deleting file...');

        fs.unlink(myDir + '/myFile', function(error) {
            if (error) {
                return callback(error);
            } else {
                return callback(null);
            }
        });
    } else {
        console.log('File does not exist...');

        return callback(null);
    }
}, function(callback) {
    fs.writeFile(myDir + '/myFile', "Hello World", function(err) {
        if(err) {
            return callback(error);
        }

        return callback(null, 'File Created');
    }); 
}], function(error, results) {
    console.error(error);
    console.log(results);
});

The waterfall function runs the tasks array of functions in series, each passing their results to the next in the array. However, if any of the tasks pass an error to their own callback, the next function is not executed, and the main callback is immediately called with the error.