node.js读取文件

node.js内置了异步读取文件的模块,可以很方便地读取文件的数据。先创建三个txt文档,在根目录下创建一个readFile.js

输入以下代码,然后在vscode的终端中输入node read(按Tab键自动生成当前js文件所在路径),回车后执行,可以看到输出的读取1.txt的结果

const fs = require('fs') //操作文件的对象
const path = require('path') //路径对象

 fs.readFile(path.join(__dirname, './files/1.txt'), 'utf-8', (err, dataStr) => {
  if (err) throw err; //错误信息
  console.log(dataStr) //读取的数据
}) ;

现在假如1.txt里的内容超级多,而2.txt里只有一条数据,如果需求是按照编号顺序依次读取文件数据,那么就应该当1.txt返回数据后再读2.txt。可是fs是异步读取数据,那么当1.txt还未返回结果的同时,2.txt可能已经读取完成并返回了结果。如下代码看起来是先执行1.txt,可输出结果必然是先打印2.txt的数据再打印1.txt的数据。

const fs = require('fs')
const path = require('path')

function readFile(path, coding,callback){
  fs.readFile(path, coding, (err, dataStr) => {
    callback(err==null?dataStr:err);  
  }) ;  
}

readFile(
    path.jon(__dirname, './files/1.txt'),
    'utf-8',
    (msg)=>{
      console.log(msg);      
});

readFile(
    path.jon (__dirname, './files/2.txt'),
    'utf-8',
    (msg)=>{
      console.log(msg);      
});

现在又假如有10个文件需要按顺序读取,则你只能在前一个文件读取完成输出数据后再读取后面的文件

const fs = require("fs");
const path = require("path");

function readFile(path, coding, callback) {
    fs.readFile(path, coding, (err, dataStr) => {
        callback(err == null ? dataStr : err);
    });
}

readFile(
    path.join(__dirname, './files/1.txt'),
    'utf-8',
    (msg) => {
        console.log(msg);

        readFile(
            path.join(__dirname, './files/2.txt'),//第一个文件读取完后读取第二个文件
            'utf-8',
            (msg) => {
                console.log(msg);

                readFile(
                    path.join(__dirname, './files/3.txt'),//第二个文件读取完后读取第三个文件
                    'utf-8',
                    (msg) => {
                        console.log(msg);

                        readFile(
                            path.join(__dirname, './files/4.txt'),
                            'utf-8',
                            (msg) => {
                                console.log(msg);

                                readFile(
                                    path.join(__dirname, './files/5.txt'),
                                    'utf-8',
                                    (msg) => {
                                        console.log(msg);

                                        readFile(
                                            path.join(__dirname, './files/6.txt'),
                                            'utf-8',
                                            (msg) => {
                                                console.log(msg);

                                                readFile(
                                                    path.join(__dirname, './files/7.txt'),
                                                    'utf-8',
                                                    (msg) => {
                                                        console.log(msg);

                                                        readFile(
                                                            path.join(__dirname, './files/8.txt'),
                                                            'utf-8',
                                                            (msg) => {
                                                                console.log(msg);

                                                                readFile(
                                                                    path.join(__dirname, './files/9.txt'),
                                                                    'utf-8',
                                                                    (msg) => {
                                                                        console.log(msg);

                                                                        readFile(
                                                                            path.join(__dirname, './files/10.txt'),
                                                                            'utf-8',
                                                                            (msg) => {
                                                                                console.log(msg);
                                                                            });
                                                                    });
                                                            });
                                                    });
                                            });
                                    });
                            });
                    });
            });
    });

以上代码叫做回调地狱

ES6的Promise异步对象

这个对象提供了在构造函数中传递一个自定义的函数,当实例化Promise对象的同时就会异步执行你传递进去的函数。Promise自身还提供一个then函数,你可以向该方法传递两个回调,一个代表执行成功后的回调(resolve),另一个代表执行失败后的回调(reject)。

function readFile(path) {
      const fs = require('fs');
      const dirPath = require('path');
      //实例化Promise时传递一个读取文件的函数让Promise对象去异步执行
      //该函数接收两个回调函数,在读取文件失败或成功时将信息传递给回调函数,让他们输出结果
      var promise = new Promise(function (resolve, reject) {
            fs.readFile(dirPath.join(__dirname, path), "utf-8", (err, data) => {
                  if (err) return reject(err); //如果读取失败则将错误信息传递给回调函数且立即返回
                  resolve(data); 
            });
      });
      //实例化Promise时就会异步执行你传递的函数
      //因为该函数是异步执行,所以下面的return promise会同一时间运行,
      //也即异步执行你传递的函数时也会执行下面的代码,返回一个promise对象到外部
      return promise;
}

//外部调用readFile得到promise对象后调用它的then方法
//then方法接收两个函数作为参数,它会把这两个函数传递给实例化Promise对象时的你传递的函数里:new Promise(function(resolve, reject))
readFile('./files/1.txt').then(
      (data) => { console.log(data) },  
      (err) => { console.log(err) }
);

Promise对象并不能减少大量回调的代码量,但通过它可以完成针对读取文件的不同需求。

需求1:需要读取3个文件,按顺序从1到3逐一读取,如果前面的文件读取失败也不影响后续文件的读取

eadFile('./files/11.txt').then(
      function(data){
            console.log(data);
            return readFile('./files/2.txt');
      },
      function(err){
            console.log(err); //第一个文件已经读取失败则直接进入错误处理,输出错误信息
            return readFile('./files/2.txt');//继续调用读取文件的函数
      }     
).then(
      function(data){
            console.log(data);
            return readFile('./files/3.txt');
      },
      function(err){
            console.log(err);
            return readFile('./files/3.txt');
      }     
).then(
      function(data){
            console.log(data);
      },
      function(err){
            console.log(err);
      }      
);

需求2:需要读取3个文件,按顺序从1到3逐一读取,如果前面的文件读取失败则不再需要继续读取后面的文件,此时不能在err里直接输出错误信息并不再调用读取文件的函数,这样做会出现问题,解决办法是在链式调用的末尾使用catch方法

readFile('./files/11.txt').then(
      function (data) {
            console.log(data);
            return readFile('./files/2.txt');
      }
).then(
      function (data) {
            console.log(data);
            return readFile('./files/3.txt');
      }
).then(
      function (data) {
            console.log(data);
      }
).catch(function (err) {
      console.log(err.message);
});

  

Javascript - 学习总目录

Javascript - 异步操作和读取文件的更多相关文章

  1. Win10系列:JavaScript写入和读取文件

    正如上面的内容中所提到的,文件保存选取器用于保存文件,通过Windows.Storage.Pickers命名空间中的FileSavePicker类的pickSaveFileAsync函数可以向指定的文 ...

  2. JS读取文件,Javascript之文件操作 (IE)

    一.功能实现核心:FileSystemObject 对象      要在javascript中实现文件操作功能,主要就是依靠FileSystemobject对象. 二.FileSystemObject ...

  3. 通过 File API 使用 JavaScript 读取文件

    原文地址:http://www.html5rocks.com/zh/tutorials/file/dndfiles/ 简介 HTML5 终于为我们提供了一种通过 File API 规范与本地文件交互的 ...

  4. javascript:FileReader对象(读取文件)

    FileReader对象 1.检测浏览器对FileReader的支持 1 if(window.FileReader) { 2 var fr = new FileReader(); 3 // add y ...

  5. javascript ActiveXObject FileSystemObject 对象,创建、复制、删除、读取文件等

    Javascript是网页制作中离不开的脚本语言,依靠它,一个网页的内容才生动活泼.富有朝气.但也许你还没有发现并应用它的一些更高级的功能吧?比如,对文件和文件夹进行读.写和删除,就象在VB.VC等高 ...

  6. File API 读取文件小结

    简单地说,File API只规定怎样从硬盘上提取文件,然后交给在网页中运行的JavaScript代码. 与以往文件上传不一样,File API不是为了向服务器提交文件设计的. 关于File API不能 ...

  7. 使用 JavaScript File API 实现文件上传

    概述 以往对于基于浏览器的应用而言,访问本地文件都是一件头疼的事情.虽然伴随着 Web 2.0 应用技术的不断发展,JavaScript 正在扮演越来越重要的角色,但是出于安全性的考虑,JavaScr ...

  8. 用仿ActionScript的语法来编写html5——第九篇,仿URLLoader读取文件

    第九篇,仿URLLoader读取文件 先看看最后的代码 function readFile(){ urlloader = new LURLLoader(); urlloader.addEventLis ...

  9. HTML5 文件域+FileReader 读取文件(一)

    在HTML5以前,HTML的文件上传域的功能具有很大的局限性,这种局限性主要体现在如下两点: 每次只能选择一个文件进行上传 客户端代码只能获取被上传文件的文件路径,无法访问实际的文件内容 一.File ...

随机推荐

  1. vue如何动态加载本地图片

    大家好,我是前端队长Daotin,想要获取更多前端精彩内容,关注我(全网同名),解锁前端成长新姿势. 以下正文: 今天遇到一个在vue文件中引入本地图片的问题,于是有了这篇文章. 通常,我们的一个im ...

  2. Hive——元数据表含义

    Hive--元数据表含义 1.VERSION   -- 查询版本信息   Field Type Comment   VER_ID bigint(20) ID主键   SCHEMA_VERSION va ...

  3. 前端开发入门到进阶第三集【获取cookie然后单点登录后重定向】

    /* var token ;//https://blog.csdn.net/qq_29207823/article/details/81745757 if( $.cookie('BBK_TOKEN') ...

  4. 微信小程序云开发-列表数据分页加载显示

    一.准备工作 1.创建数据库nums,向数据库中导入108条数据 2.修改数据库表nums的权限 二.新建页面ListPaginated 1.wxml文件 <!-- 显示列表数据 --> ...

  5. mysql为什么用b+树做索引

    关键字就是key的意思 一.B-Tree的性质 1.定义任意非叶子结点最多只有M个儿子,且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点的儿子数为[M/2, M]: ...

  6. 论文笔记:(ICCV2019)KPConv: Flexible and Deformable Convolution for Point Clouds

    目录 摘要 一.引言 二.相关工作 投影网络 图卷积网络 逐点多层感知器网络 点卷积网络 三.核点卷积 3.1由点定义的核函数 3.2刚性的或可变形的核 3.3核点网络层 3.4核点网络架构 四.实验 ...

  7. DC-6 靶机渗透测试

    DC-6 渗透测试 冲冲冲,好好学习 . 收获总结写在文末. 操作机:kali 172.66.66.129 靶机:DC-4 172.66.66.136 网络模式:NAT 上来一波 netdiscove ...

  8. 「GM_脚本」获取 GitHub 项目文件的 jsDelivr CDN 地址「好像没啥用系列」

    基本信息: name:「 GitHub 」获取文件的 jsDelivr 地址 desc:获取项目文件的 CDN 地址 url: https://github.com/wdssmq/userscript ...

  9. Python 统计列表中重复元素的个数并返回其索引值

    需求:统计列表list1中元素3的个数,并返回每个元素的索引 list1 = [3, 3, 8, 9, 2, 10, 6, 2, 8, 3, 4, 5, 5, 4, 1, 5, 9, 7, 10, 2 ...

  10. 2020Android面试重难点之Handler机制,含字节、京东、腾讯经典面试真题解析!

    Handler 在整个 Android 开发体系中占据着很重要的地位,对开发者来说起到的作用很明确,就是为了实现线程切换或者是执行延时任务,稍微更高级一点的用法可能是为了保证多个任务在执行时的有序性. ...