使用节点fs函数的Javascript执行顺序

使用节点fs函数的Javascript执行顺序,javascript,promise,async-await,Javascript,Promise,Async Await,我一直在尝试让下面的代码按照我希望的方式执行。即将1 2 3打印到控制台 const fs = require('fs'); const doSomthingWithFile = (file, number) => { fs.readFile(file, () => { console.log(number); }); }; fs.readdir('./', (err, files) => { for (let i = 0; i < files.l

我一直在尝试让下面的代码按照我希望的方式执行。即将
1 2 3
打印到控制台

const fs = require('fs');

const doSomthingWithFile = (file, number) => {
  fs.readFile(file, () => {
    console.log(number);
  });
};

fs.readdir('./', (err, files) => {
  for (let i = 0; i < files.length; i++) {
    doSomthingWithFile(files[i], 1);
  }
  for (let i = 0; i < files.length; i++) {
    doSomthingWithFile(files[i], 2);
  }
});

console.log(3);
const fs=require('fs');
const dosomthinghithfile=(文件,编号)=>{
fs.readFile(文件,()=>{
控制台日志(编号);
});
};
fs.readdir(“./”,(错误,文件)=>{
for(设i=0;i
我一直在尝试使用async/await和返回承诺的函数,但我猜我做得都不对,因为我一直将
3 1 2
作为输出

我如何确保它按照我希望的顺序执行。这意味着首先读取目录。然后等待第一个
doSomthingWithFile()
完成,然后再启动第二个
doSomthingWithFile()
回调,直到
readdir()
完成,再使用最后一个log语句


就像我说的,我一直试图在这个网站上搜索类似的主题,但仍然无法让它工作。例如,使回调函数异步并等待其中的函数不起作用(或者我一定做得不正确)。

如果使doSomethingWithFile函数返回承诺,则可以等待它,以便在前一次迭代解决之前,永远不会执行下一次迭代。像这样的方法应该会奏效:

const fs=require('fs');
const dosomthinghithfile=(文件,编号)=>新承诺((解决,拒绝)=>{
fs.readFile(文件,()=>{
控制台日志(编号)
解决()
});
});
fs.readdir('./',异步(错误,文件)=>{
for(设i=0;i
这里发生了什么:

  • readdir回调使之异步
  • doSomthingWithFile函数返回一个承诺,该承诺在异步readFile函数完成时解析。我们通过调用readFile函数回调中的
    resolve
    方法来实现这一点
  • 等待doSomthingWithFile调用的返回。这确保了操作发生的顺序是一致的
如果希望同步,请使用同步方法(
fs.readdirSync
fs.readFileSync
)。以下是
async/await
版本:

const fsp=require('fs')。承诺;
const dosomthinghithfile=async(文件,编号)=>{
等待fsp.readFile(文件);
控制台日志(编号);
};
(async()=>{//async IILife,因为还不支持全局等待)
const files=wait fsp.readdir('./');
for(设i=0;i
异步/await和retun承诺的函数
-这就是如何做到的,但是您的示例没有显示任何这方面的指示。您可以分享您的尝试吗?您需要以异步方式执行迭代,以便在上一次迭代完成之前不会触发下一次迭代。我建议使用递归风格的while循环。这里的问题和我的答案非常相似:。通过使用promises
fs.promises.readdir()
fs.promises.readFile()
async/await
解决了这个问题。而且,这里有100多个关于stackoverflow的重复问题/答案,用于循环中的异步操作。超级常见的问题。@jfriend00他似乎缺少事件循环机制以及javascript在幕后是如何工作的。你可以使用
fs
sync方法吗?当
fs.promises
包含内置的promisified方法时,手动提示
fs
函数没有意义。我从未使用过fs.promises,但听起来不错。这是一个普遍适用的解决方案,同样有效。好吧,这是值得学习的,因为它是
fs
模块的未来。还有一个更好的面向对象文件句柄(奇怪的是,最初的
fs
filehandle只是标准库函数的一个过程实现,而不是将问题视为方法的对象。是的,手动提示是有效的,但它不再是推荐的方式。为什么不再是推荐的方式?因为它需要多写几行?是吗
fs.promissions
解决了
fs
中存在的奇怪文件句柄的问题?如何解决?因为它是一种内置的处理方式,允许您完全通过promissions来管理所有文件操作的控制流和错误处理。为什么您会建议某人在promisify v版本已经存在,你只需要使用它。为什么你不想教别人更快、更短、内置的方法呢?而且,一旦他们知道了
fs.promises
,他们就可以看到你可以使用它的所有其他功能。我不知道你所说的“fs中存在的奇怪文件句柄”是什么意思.FYI,我建议做
const fsp=require('fs')。承诺
,然后参考
fsp
,而不是
fs
,这样代码的读者就知道人们可能习惯的不是标准的
fs
,而是承诺版本。