摘要:總結執行方法本質上相當于注冊一個回調函數,而函數結合函數就是一種更直觀的注冊回調函數的方式。函數負責異步執行交出執行權,而函數負責注冊回調返回執行權,執行下一步,兩者結合從而自動執行函數。
今天又看了一遍阮一峰老師的《Thunk 函數的含義和用法》,這里整理一下自己的理解:
在 JavaScript 語言中,Thunk 函數替換的不是表達式,而是多參數函數,將其替換成單參數的版本,且只接受回調函數作為參數。
// 正常版本的readFile(多參數版本) fs.readFile(fileName, callback); // Thunk版本的readFile(單參數版本) var readFileThunk = Thunk(fileName); readFileThunk(callback); var Thunk = function (fileName){ return function (callback){ return fs.readFile(fileName, callback); }; };
以讀取文件為例。下面的 Generator 函數封裝了兩個異步操作。
var fs = require("fs"); var thunkify = require("thunkify"); var readFile = thunkify(fs.readFile); var gen = function* (){ var r1 = yield readFile("/etc/fstab"); // 2. 讀取文件一 console.log(r1.toString()); var r2 = yield readFile("/etc/shells");// 5. 讀取文件二 console.log(r2.toString()); };
手動執行方式:
var g = gen();// 0. 初始化 var r1 = g.next();// 1. 執行下一步,返回的r1就是generator指針:{value, done},而這里的value其實就是一個thunk函數,這個thunk函數以回調函數作為參數 r1.value(function(err, data){// 3. 文件一讀取完成的回調函數 if (err) throw err; var r2 = g.next(data);// 4. 執行下一步 r2.value(function(err, data){ // 文件二讀取完成的回調函數 if (err) throw err; g.next(data); }); });
總的來說,其實就是利用thunk函數,把需要做的操作和對應的回調函數,從fn(operation, callback)改成了fn(operation)(callback)的形式。
為什么要這么做?
是因為generator函數在yield返回后,不會自動往下執行,如果寫成:
var gen = function* (){ var r1 = yield readFile("/etc/fstab", gen.next()); // 這時gen還沒有初始化,不是一個generator指針,所以沒有next方法,而gen() !== gen(),所以也不能寫成gen().next() console.log(r1.toString()); };
也沒法自動執行,所以將回調函數分離到第二步,然后在回調函數里(這時generator肯定已經初始化完了,不然沒法執行到回調函數)執行generator指針的next方法,走到下一步。
總結:執行value方法本質上相當于注冊一個回調函數,而generator函數結合thunk函數就是一種更直觀的注冊回調函數的方式。generator函數負責異步執行(交出執行權),而thunk函數負責注冊回調(返回執行權,執行下一步),兩者結合從而自動執行generator函數。
如果有任何理解不妥當的地方,歡迎指正交流。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89379.html
摘要:為了更加方便的處理異步操作問題,現在最新的前端框架生態都開始用上了和,有的甚至已經開始使用最新的語法了,這兩樣都是基于自動執行的原理。這里就簡單理解下自執行及語法原理一函數函數指的是能將執行結果傳入回調函數,并將該回調函數返回的函數。 為了更加方便的處理異步操作問題,現在最新的前端框架生態都開始用上了Generator和yield,有的甚至已經開始使用最新的async、await語法了...
摘要:傳統的異步方法回調函數事件監聽發布訂閱之前寫過一篇關于的文章,里邊寫過關于異步的一些概念。內部函數就是的回調函數,函數首先把函數的指針指向函數的下一步方法,如果沒有,就把函數傳給函數屬性,否則直接退出。 Generator函數與異步編程 因為js是單線程語言,所以需要異步編程的存在,要不效率太低會卡死。 傳統的異步方法 回調函數 事件監聽 發布/訂閱 Promise 之前寫過一篇關...
摘要:關于協程和中的什么是協程進程和線程眾所周知,進程和線程都是一個時間段的描述,是工作時間段的描述,不過是顆粒大小不同,進程是資源分配的最小單位,線程是調度的最小單位。子程序就是協程的一種特例。 關于協程和 ES6 中的 Generator 什么是協程? 進程和線程 眾所周知,進程和線程都是一個時間段的描述,是CPU工作時間段的描述,不過是顆粒大小不同,進程是 CPU 資源分配的最小單位,...
摘要:的異步完成整個異步環節的有事件循環觀察者請求對象以及線程池。執行回調組裝好請求對象送入線程池等待執行,實際上是完成了異步的第一部分,回調通知是第二部分。異步編程是首個將異步大規模帶到應用層面的平臺。 showImg(https://segmentfault.com/img/remote/1460000011303472); 本文首發在個人博客:http://muyunyun.cn/po...
摘要:沿用上面的例子,把包裝成一個對象這個回調就是等價于通過在里執行回調函數,獲取到上一步操作的結果和交回執行權,并把值傳遞回函數內部,實現了遞歸執行進一步封裝,可以得到以下的代碼遞歸執行 以前看過的內容,感覺忘得差不多,最近抽空又看了一次,果然書讀百遍其義自見 Generator的執行 Generator函數可以實現函數內外的數據交換和執行權交換。 從第一次調用next開始,從函數頭部開始...
閱讀 2753·2021-11-22 14:45
閱讀 896·2021-10-15 09:41
閱讀 1058·2021-09-27 13:35
閱讀 3662·2021-09-09 11:56
閱讀 2626·2019-08-30 13:03
閱讀 3191·2019-08-29 16:32
閱讀 3296·2019-08-26 13:49
閱讀 766·2019-08-26 10:35