好比咱們如今有個讀取文件的需求,那麼用nodejs,剛開始咱們的代碼會這麼寫javascript
var fs=require('fs'); var path=require('path'); function readFile(fpath){ fs.readFile(fpath,'utf-8',(err,data)=>{ if(err) throw err; return data; }) } let res=readFile('App.vue'); //這裏打印爲undefined 由於fs.readFile是異步的,主線程在遇到異步函數時,會將異步任務放到隊列中,而後 //繼續執行,因此這裏獲得undefined console.log(res);
解決思路1:利用回調函數,獲取異步結果vue
function readFile(fpath,callback){ fs.readFile(fpath,'utf-8',(err,data)=>{ if(err) throw err; throw new Error('er hui'); callback(data); }) } //但這裏又存在一個問題,若是這個函數常常發生異常,這樣的話,經過回調仍是拿不到結果的, //咱們應該將處理的結果告訴給調用者,由調用者決定要若是處理結果,包括異常結果 readFile('App.vue',result=>{ console.log(result) }); 改進以下,將回調函數定義成有兩個參數: function readFile(fpath,callback){ fs.readFile(fpath,'utf-8',(err,data)=>{ if(err) callback(err); callback(null,data); }) } //但這裏又存在一個問題,若是這個函數常常發生異常,這樣的話,經過回調仍是拿不到結果的, //咱們應該將處理的結果告訴給調用者,由調用者決定要若是處理結果,包括異常結果 readFile('App.vue2',(err,result)=>{ if(err) throw err; console.log(result) }); //改進思路3 //咱們這樣寫是沒問題了,但對於初學者來講可能有點很差理解,這裏咱們能夠規定指定的函數來處理成功的結果和異常結果 function readFile(fpath,succ,fail){ fs.readFile(fpath,'utf-8',(err,data)=>{ if(err) return fail(err); succ(data); }) } readFile('App.vue',function (data) { console.log('succ'); console.log(data); },function (err) { console.log('fail'); console.log(err); });
假設有個需求,按順序讀取文件。那麼咱們可能會這樣寫java
readFile('1.txt',function (data) { console.log(data); readFile('2.js',function (data) { console.log(data); readFile('3.js',function (data) { console.log(data); }); }); }); 這就是一個典型的回調地獄問題, 解決辦法:使用ES6 的 Promise //1.Promise 是一個構造函數,既然是構造函數,那麼咱們就能夠 new Promise() 獲得一個 Promise 實例 //2.在Promise 上,有兩個函數,分別叫 resolve(成功後的回調),和 reject(失敗後的回調) 3,在Promise 構造函數的 prototype 屬性上,有個.then 方法,也就是說只要 Promise 構造函數建立的實例,均可以訪問到 .then() 方法 4,Promise 表示一個異步操做,每當咱們 new 一個 Promise 的實例,這個實例就表示一個 具體的異步操做 5,既然Promise 建立的實例,是一個異步操做,那麼這個異步操做的結果,只有兩種狀態 5.1 異步成功了 5.2 異步失敗了 5.3 因爲Promise 的實例,是一個異步操做,因此內部拿到操做的結果後,沒法使用return 把操做的結果返回給調用者,這時候,只能使用回調函數的形式,把成功或失敗的結果返回 給調用者 每當new 一個 Promise 實例的時候,會當即執行這個異步操做中的代碼 注意:經過.then 指定回調函數的時候,成功的回調函數必須傳。可是失敗的函數的回調 能夠不傳 當第一個回調報錯時,後面的異步操做都不執行了,當須要第一個異步操做不影響後續回調 ,須要傳入異常處理函數 當後續的Promise 操做依賴於前面的Promise 操做的結果,那麼可使用catch 將異常抓住 也就是說,當前面任意一個Promise 執行出錯,都會被catch 抓住 function readFile(fpath){ var promise=new Promise(function (resolve,reject) { fs.readFile(fpath,'utf-8',(err,data)=>{ if(err) return reject(err); resolve(data); }) }); return promise; } var promise=readFile('Ap2p.vue'); promise.then(function (data) { console.log('2111') console.log(data) return readFile('main.js') }).then(function (data) { console.log('222') return readFile('fs.js') }).then(function (data) { console.log('333') console.log(data) }).catch(function (err) { console.log('err===============') console.log(err) });
補充:console.dir() 能夠顯示一個對象全部的屬性和方法。node