Node读写文件和通过promise处理异步

一. 在之前的node版本中读写文件可以通过fs模块的readFile() 和 readFileSync()方法。其中,readFile()为异步读取,readFileSync()为同步读取。

  • sync 同步
  • async 异步

下面举例说明两种操作

先结论:异步读取文件的时候由操作系统在后台进行读取,不会阻碍下面的代码执行。同步读取的时候会阻碍下面的代码执行。
test.js

var fs = require('fs');                //获取fs模块
console.log('start async read');        //异步读取开始
fs.readFile('test2.js',function(error,date){    //读取文件,回调函数第一个参数表示错误信息,第二个参数为读取的文本内容
    if(error){
        console.log(error);
    }else{
        console.log('end async read');    //异步读取结束
    }
});


console.log('start sync read'); //同步读取开始
var date = fs.readFileSync('log.txt','utf-8');
console.log('end sync read');    //同步读取结束

结果:
在这里插入图片描述

看出是按这个顺序执行的:异步读取开始--------------->同步读取开始--------------------->同步读取结束---------------->异步读取结束

异步读取没有结束,同步读取就完成了。

结论:异步读取没有阻塞下面代码的执行。

调换一下代码就更明显了

var fs = require('fs');                //获取fs模块

console.log('start sync read'); //同步读取开始
var date = fs.readFileSync('log.txt','utf-8');
console.log('end sync read');    //同步读取结束


console.log('start async read');        //异步读取开始
fs.readFile('test2.js',function(error,date){    //读取文件,回调函数第一个参数表示错误信息,第二个参数为读取的文本内容
    if(error){
        console.log(error);
    }else{
        console.log('end async read');    //异步读取结束
    }
});

在这里插入图片描述
看出是按这个顺序执行的:同步读取开始--------->同步读取结束-------->异步读取开始------->异步读取结束

结论:同步读取 阻塞下面代码执行。

二. 除此之外,我们还可以用fs模块里的promises里的readFile和writeFile来读写文件

在nodejs文档中,v10版本里新增了通过promise来处理异步操作读取文件的API,即fs模块里的promises的readFile()和writeFile()

const {promises: {readFile, writeFile}} = require('fs');
(async () => {
    let content = await readFile('./data.txt', 'utf8');
    await writeFile('2.txt', content, 'utf8');
    console.log('ok');
})();

注意!!! forEach如何处理异步,请用for … of

在这段代码中,存在一个常见的 JavaScript 异步操作问题。具体来说,files.forEach 中的异步操作无法按预期方式工作。这是因为 forEach 方法无法正确处理异步函数的返回值或等待异步函数的完成。

为了解决这个问题,您可以使用 for...of 循环来遍历文件数组,并在其中使用 await 关键字来等待每个异步操作的完成。这样可以确保每个文件的内容都能被正确处理,并且可以正确地构建 Markdown 内容。

下面是修改后的代码示例:

const getMdContent = async () => {
  let mdResult = ''
  for (const file of files) {
    try {
      const dataString = await readFile(file)
      // 使用 eval 解析文件内容
      const moduleWrapper = new Function('module', 'exports', dataString)
      const module = { exports: {} }
      moduleWrapper(module, module.exports)

      // 获取questions
      const questions = module.exports.questions ?? []
      mdResult += generateMarkdown(questions) + '\n\n'
    } catch (error) {
      console.error('Error parsing file content:', error)
    }
  }
  return mdResult
}

在这个修改后的代码中,我们使用了 for...of 循环来遍历文件数组,并在其中使用 await 关键字来等待每个异步操作的完成。这样可以确保每个文件的内容都能被正确处理,并且可以正确地构建 Markdown 内容。

通过这种方式,您可以解决异步操作无法按预期方式工作的问题,确保每个文件的内容都能被正确处理。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Promise中执行异步操作的方法有以下几种: 1. 使用`setTimeout`或`setInterval`:可以使用`setTimeout`或`setInterval`函数来执行异步操作,例如模拟延迟或定时执行某个任务。 ```javascript new Promise((resolve, reject) => { setTimeout(() => { resolve('Operation succeeded'); }, 2000); }); ``` 2. 发起网络请求:使用浏览器提供的`fetch`或`XMLHttpRequest`等API进行网络请求,这些API都是异步的,可以将其包装在Promise中。 ```javascript new Promise((resolve, reject) => { fetch('https://api.example.com/data') .then(response => response.json()) .then(data => resolve(data)) .catch(error => reject(error)); }); ``` 3. 处理文件读写:使用Node.js提供的文件系统模块(如`fs`)进行文件读写操作,这些操作也是异步的。 ```javascript const fs = require('fs'); new Promise((resolve, reject) => { fs.readFile('path/to/file', 'utf8', (err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); ``` 4. 执行数据库查询:如果使用的是异步的数据库操作库(如Mongoose、Sequelize等),则可以将数据库查询操作包装在Promise中。 ```javascript new Promise((resolve, reject) => { User.findOne({ username: 'john' }) .then(user => resolve(user)) .catch(error => reject(error)); }); ``` 以上是一些常见的异步操作示例,你可以根据具体的需求选择适合的方法来执行异步操作,并将其包装在Promise中以便进行状态管理和链式调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

. . . . .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值