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. MapReduce显示最受欢迎的Top10课程(按照课程编号)

    上篇博客已经说过,会将代码进行优化,并通过TreeMap进行排序实现,现在简单说明一下代码的思路. 项目以上传到github:https://github.com/yandashan/MapReduc ...

  2. Map集合笔记

    一.Map集合的特点 Map集合是一个双列集合 Map中的元素,key和value的数据类型可以相同,也可以不同. Map中的元素,key是允许重复的,value是可以重复的 Map中的元素,key和 ...

  3. 一个很多人不知道的SpringBoot小技能!!

    大家好,我是冰河~~ 最近,发现很多小伙伴在修改了SpringBoot的配置文件后,都要重新编译整个项目,极大的浪费了开发时间.我身边就有很多小伙伴一直是这样做的.那么,有没有什么方式能够修改配置文件 ...

  4. 前端早读课:JavaScript函数的6个基本术语

    lambdas(匿名函数) 箭头函数. const lambda = (a, b) => a + b; first-class functions(头等函数) 该类型可以用作变量的值. docu ...

  5. kubernetes/k8s CSI分析-容器存储接口分析

    更多 k8s CSI 的分析,可以查看这篇博客kubernetes ceph-csi分析,以 ceph-csi 为例,做了详细的源码分析. 概述 kubernetes的设计初衷是支持可插拔架构,从而利 ...

  6. mybatis-7-缓存

    1. 一级缓存: SqlSession 级别, 默认开启, 并且不能关闭 操作数据库是需要创建 SqlSession 对象, 在对象中有一个 HashMap 用于存储缓存数据, 不同的 SqlSess ...

  7. Python如何将py文件打包成exe

    安装pyinstaller 打开cmd窗口,输入pip install pyinstaller,命令行输出successfully表示成功. 生成exe文件 一.单个py文件 在py文件目录下,打开c ...

  8. C++第四十九篇 -- 将一个项目Copy到另一台电脑

    最近写项目,由于设备原因,需要将一台电脑的项目拷贝到另一台电脑上,在另一个电脑上继续编写.由于配置属性原因,最终还是在另一台电脑上创建了新项目,只是把这些cpp文件都复制过去了,然后重新部署属性. 背 ...

  9. js排序——sort()排序用法

    sort() 方法用于对数组的元素进行排序,并返回数组.默认排序顺序是根据字符串Unicode码点. 语法:array.sort(fun):参数fun可选.规定排序顺序.必须是函数.注:如果调用该方法 ...

  10. vue的项目初始化

    1.创建文件 blog 2.下载安装node mongoose 3.(1)vue创建后端项目文件 vue create admin (2)vue创建前端项目文件 vue create web (3)新 ...