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-preview报错Cannot read property 'open' of undefined

    最近在做一个vue项目中时,需要使用vue-preview插件制作缩略图,首先在终端使用npm i vue-preview -S指令安装了vue-preview插件,然后在main.js中,导入并引用 ...

  2. 标准化R包开发流程

    3个武器: devtools:各种开发小工具的合集,让开发变得简单,非常实用 roxygens:通过注释的方式,生成文档,远离LaTex的烦恼 testthat:单元测试,让R包稳定.健壮.减少升级的 ...

  3. Spring,Spring-boot(一)

    前言 Spring作为java开源世界第一开源框架,已经成为事实上的Java EE开发标准. 最根本的使命就是简化Java开发. 不重复制造车轮 Don't reinvent the wheel .从 ...

  4. selenium定位,操作元素

    1.定位方式 1.id driver.find_element_by_id('username').send_keys('byhy') 2.name driver.find_element_by_na ...

  5. gos-log高性能大日志检索中台

    gos-log 基于Go语言的轻量级高性能的大日志检索系统 开源地址 gos-log https://gitee.com/dianjiu/gos-log https://github.com/dian ...

  6. 不想用Spring全家桶?试试这个国产JFinal框架

    前言 逃离北上广从广州回老家南宁,入职这家公司用的技术是JFinal,借此机会得以学习这个国产的MVC框架,经过一段时间的学习,基于之前的经验搭建一个通用项目jfinal-demo jfinal-de ...

  7. Dubbo 实现一个Route Factory(用于灰度发布)

    Dubbo 可以实现的扩展很多, 官方文档在这: https://dubbo.apache.org/zh/docs/v2.7/dev/impls/ (太简单了....) 下面我们实现一个Route F ...

  8. netty系列之:Event、Handler和Pipeline

    目录 简介 ChannelPipeline ChannelHandler ChannelHandlerContext ChannelHandler中的状态变量 异步Handler 总结 简介 上一节我 ...

  9. Android开发失业六个月了,无限的焦虑

    最近到网上看到这样一个帖子: Android开发,坐标魔都:目前为止已经失业六个月,找工作期间,尤其是最近两天确实心态不好.要么没有面试,要么给的工资不符合预期( hr 压价太狠了,原先说的 19k, ...

  10. ubuntu 权限管理设置

    最近工作中涉及文件操作的内容较多,所以会出现各种各样的权限不足问题,导致操作失败.下面就来讲解下我碰到这种问题是通过什么的方法解决的 一.用户和权限 用户 是 Linux 系统工作中重要的一环,用户管 ...