指令没有执行到正确的顺序与nodejs

问题描述:

我是新的nodejs和试图在编码时动态捕捉多个css文件。包chokidar允许我在修改文件时调用函数,但是我在执行时遇到问题。指令没有执行到正确的顺序与nodejs

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()在目录更新之前执行的,而不是之后,因此它试图猫,只是已经被删除的文件。为什么?

我知道,是的NodeJS执行功能以同步的方式,但我不能找到一种方法来解决这个问题。我尝试异步,但我不能声明两个函数之间的变量,我无法设法使其工作。

+0

不要在生产中使用,虽然功能的setTimeout,你永远知道什么值,你会硬编码,并在那里将开始断裂。 –

如果它不能在回调存在,则使用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); 
     }); 
}); 
+0

因为这是最简单的,因为我不担心阻止开发的代码,我用你的解决方案10毫秒,它的工作。谢谢 ! – WaspCo

Nodejs是异步的,这里也是同样的事情发生。 Concat功能在取消链接前被调用。您可以尝试取消链接Concat的功能本身里面的文件,使事情同步这样的 -

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使用是删除fs.stat之前存在或不存在,如果不存在然后将concat的逻辑放入else,如果存在正常的删除和concat逻辑。

希望它有帮助!

您遇到的问题是您的concat函数在调用unlink删除文件之前被调用。你可以通过嵌套回调来防止这种情况发生。不过,如果您使用async这样的模块,则可能会有更好的control flow,并防止自己处理Callback Hell

下面是关于如何使用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); 
}); 

waterfall函数运行的功能串联的任务阵列, 每个经过它们的结果到阵列中的下一个。但是,如果任务的任何 都将错误传递给其自己的回调,则下一个函数 未执行,并且主回调立即被调用,并且出现 错误。

+0

我没有结束使用您的解决方案,但它似乎是最严格的一个。我试图使用异步但失败,你的说明帮助我理解我的错误,所以谢谢你 – WaspCo