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. debian9 python环境设置

    file /usr/bin/python which python2 which python3 mv /usr/bin/python /usr/bin/python_bk ln -s /usr/bi ...

  2. 使用Angular CDK实现一个Service弹出Toast组件

    在Angular中,官方团队在开发Material组件库的同时,顺手做了一套Component dev kit,也就是在Angular世界中大名鼎鼎的CDK,这套工具包提供了非常多的前端开发的通用功能 ...

  3. WLS中Linux与Windows间的环境共享

    Reference 更多cmd.exe帮助参考 (cmd_helps)[https://ss64.com/nt/cmd.html] (WSL备份,windows Docker安装)[https://w ...

  4. odoo14里面的用户登录log记录

    一.继承userlog,添加字段 # -*- coding: utf-8 -*- from odoo import models, fields, api from odoo.http import ...

  5. kubernetes/k8s CRI分析-容器运行时接口分析

    关联博客:kubernetes/k8s CSI分析-容器存储接口分析 概述 kubernetes的设计初衷是支持可插拔架构,从而利于扩展kubernetes的功能.在此架构思想下,kubernetes ...

  6. ;~ 小部分AutoHotkey脚本源代码测试模板样板.ahk

    ; ;~ 小部分AutoHotkey脚本源代码测试模板样板.ahk ;~ 请把一行或几行少量代码放到此文件中实际测试一下,;~ 看看测试结果如何,等到能够实现代码功能时再复制到自己的脚本代码文件中;~ ...

  7. 使用C#winform编写渗透测试工具--SQL注入

    使用C#winform编写渗透测试工具--SQL注入 本篇文章主要介绍使用C#winform编写渗透测试工具,实现SQL注入的功能.使用python编写SQL注入脚本,基于get显错注入的方式进行数据 ...

  8. 记录21.08.04 — mybatis入门学习

    mybatis入门 mybatis简介 MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工 ...

  9. 记录21.07.20 —— js语言回顾

    js语言回顾 1.语法 a并没有声明,也可以输出,不会报错. 添加一条语句 则需要声明,称之为严谨语法 2.数组 2.1数组遍历三种方法 for-in与for-of forEach forEach调用 ...

  10. Mol Cell | 张令强/贺福初/魏文毅/刘翠华揭示线性泛素化调控血管生成新机制

    景杰学术 | 报道 泛素化修饰作为主要的蛋白质翻译后修饰之一,与细胞周期.应激反应.信号传导和DNA损伤修复等几乎所有的生命活动密切相关[1].泛素分子通常含有7个赖氨酸残基,通过这些残基可以和其他泛 ...