首先看一個例子:讀取package.json下的文件,并將讀取的數據(若讀取失敗)打印出來
// 導入fs和thunkify模塊
var thunkify = require('thunkify');
var fs = require('fs');// 定義讀取文件的函數read
var read = thunkify(fs.readFile);// 調用read函數讀取package.json下的文件.并對數據進行處理
read('pacage.json')(function(err, str) {console.log(err);console.log(str);
}
以上是以同步方式書寫的,異步讀取文件并,對文件信息進行處理的操作…
下面是thinkify的源碼,閱讀一下就好…
function thunkify(fn) {return function() {// 傳入的參數,放在數組args中var args = new Array(arguments.length);// 保存環境.放在ctx中var ctx = this;for (var i = 0; i < args.length; ++i) {args[i] = arguments[i];}return function (done) {var called;args.push(function () {if (called) return;called = true;done.apply(null, arguments);});try {fn.apply(ctx, args);} catch (err) {done(err);}}}
};
看個實例:
function f(a, b, callback) {var sum = a + b;callback(sum);callback(sum);
}var ft = thunkify(f);
var print = console.log.bind(console);
ft(1, 2)(print);
函數本質上是對數據的處理,因此分析函數的一個比較好的方法是把參數都打出來,然后找到其中的聯系…
下面將幾個關鍵的數據打印到控制臺,
// 可以很清楚看見fn就是自己定義的f,對應的語句就是var ft = thunkify(f). 和 function thunkify(fn)// args來自ft(1, 2)(print) 而 print 來自 var print = console.log.bind(console);對應的再fhunkify中,是 (第一個)return 語句 args = new Array(arguments.length), for(var i = 0; i < args.length; ++i){args[i] = aguments[i];}// 在第2層return 里面接收參數給done,然后定義了一個called函數(確保回調函數只調用一次),具體實現在args.push里面,若已經調用過,會return ,對應if(called) return;經過args.push后,可以看見args2變為3個., 即多了一個函數就是callback函數,對應實例也就是print = console.log.bind(console).// 最后是一個try...catch塊.嘗試使用f(a,b,callback).. 參數都在args里面// 這樣寫的好處是:異步實現,方便閱讀.. 前面ft(1,2)可以是一個異步操作,如讀取文件,或ajax請求網頁數據,后面是一個回調函數(cb),這樣就是一個同步的寫法..
參考《ES6標準入門》(第3版)P364~P365