Javascript - 異步操做和讀取文件

node.js讀取文件

node.js內置了異步讀取文件的模塊,能夠很方便地讀取文件的數據。先建立三個txt文檔,在根目錄下建立一個readFile.jshtml

輸入如下代碼,而後在vscode的終端中輸入node read(按Tab鍵自動生成當前js文件所在路徑),回車後執行,能夠看到輸出的讀取1.txt的結果node

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的數據。promise

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);
                                                                            });
                                                                    });
                                                            });
                                                    });
                                            });
                                    });
                            });
                    });
            });
    });

以上代碼叫作回調地獄ide

 

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對象並不能減小大量回調的代碼量,但經過它能夠完成針對讀取文件的不一樣需求。post

需求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方法ui

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 - 學習總目錄spa

相關文章
相關標籤/搜索