Nodejs異步回調處理

目錄

一、前言

二、異步與回調

三、解決方案


一、前言

先看一個例子:

const fs = require('fs')
//a.txt文件內容是aaa
fs.readFile('a.txt', 'utf8', function(err, data){
    console.log(data);
})

console.log("123456");

這個例子的預期功能,就是讀取並輸出a.txt文件的內容"aaa",然後再輸出“123456”,然而看輸出卻與預期不一樣:

這就引出了異步和回調的概念。

 

二、異步與回調

nodejs是一個單線程函數,主線程在執行的時候,一旦發生了異步處理(文件讀寫、網絡請求、定時任務、讀取數據庫等),一方面,js會讓操作系統相關部件去處理這些請求,另一方面,它會繼續執行後面的代碼,這就是異步。

然後,當js讓操作系統相關部件去處理這些請求,當這些請求有返回數據時(比如網絡請求返回數據了),js就會調用相應的事件對象裏的處理函數,這個處理函數,就是回調函數。

通俗的講,就是js不管你有沒處理完異步函數,就開始往下走了,除非異步函數處理的速度極快極快,才能出現“按代碼順序執行”的情況。

 

三、解決方案

①把需後面執行的程序,放到異步函數內,例如如下:

const fs = require('fs')
//a.txt文件內容是aaa
fs.readFile('a.txt', 'utf8', function(err, data){
    console.log(data);
    console.log("123456");
})

這樣做可以解決問題,但是會引入一個問題,就是如果嵌套多了,代碼會不美觀,這種寫法又稱爲“回調地獄”

 

②使用Promise

Promise是在ES6的標準中出現的,也就是nodejs v8.5.0以上版本,低於這個版本不能使用(版本查看命令:node -v)

Promise構造函數接受一個函數作爲參數,該函數的兩個參數分別是resolve和reject,它們是兩個函數,由js引擎內部提供,不用自己部署。

resolved函數,在異步操作成功時調用,並將異步操作的結果,作爲參數傳遞出去;reject函數,在異步操作失敗時調用,並將異步操作報出的錯誤,作爲參數傳遞出去。

const fs = require('fs')
const aPromise = new Promise((resolve, reject) => {
    fs.readFile('a.txt', 'utf8', function(err, data){
        if (err) return reject(err)
        resolve(data)
    })
})

const bPromise = new Promise((resolve, reject) => {
    resolve("123456");
})

//then的作用執行Promise並返回結果
//這裏可以理解爲:aPromise.then(執行結果),return bPromise, bPromise.then(執行結果)
aPromise
    .then(Content1 => {
        console.log(Content1);
        return bPromise
    })
    .then(Content2 => {
        console.log(Content2);
    })

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章