亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

JS Thunk 函數的含義和用法實例總結

瀏覽:65日期:2024-05-13 15:45:29

本文實例講述了JS Thunk 函數的含義和用法。分享給大家供大家參考,具體如下:

前面我們已經學習過了Generator 函數的優勢和使用場景。

這篇文章我們繼續學習阮老師的第二篇文章,Thunk 函數的含義和用法

說實話,在這之前是沒聽過這個詞的,但其實如果你對犀牛書里的不完全函數有認真看過的話理解起來也不是很費勁。

首先什么是 thunk 函數?

很多場景下我們都會陷入一個問題,就是函數參數的求值時間。

是函數調用時即求值還是在函數內使用時才求值?

var x = 1;function f(m){ return m * 2; }f(x + 5)//我們把在調用時就計算的方式稱為傳值調用,等同于:f(6)//我們把在函數內部使用時才求值的方式稱為傳名調用,等同于:return (x + 5) * 2;

兩種方式各有利弊,傳值調用比較簡單,但是如果計算后的結果沒有在程序中使用的話,損失就有點大。因此有很多場景都傾向于傳名調用。

但是像 C,java 的編譯方式都是固定的,如何基于現有基礎改變程序的執行方式。

比較常見的是將想要傳名調用的參數放到一個臨時函數之中,把臨時函數當做參數,只在使用的時候執行。

這個包裝參數的臨時函數就叫 Thunk 函數。我們試一下用 Thunk 函數改寫一下上面的例子:

function f(m){ return m * 2; } f(x + 5); // 等同于 var thunk = function () { return x + 5;}; function f(thunk){ return thunk() * 2;}

其實這里我倒覺得可以翻翻犀牛書里的不完全函數,跟 Thunk 函數一個道理,

通過 return 一個 function 來實現傳名調用。

老師也順便介紹了用在生產環境的 Thunkify 模塊

我們看一下源碼,還是有一些好玩的地方的。

function thunkify(fn){ //全局返回一個臨時函數 return function(){ var args = new Array(arguments.length); var ctx = this; for(var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } //上面一段將參數copy到args return function(done){ var called; args.push(function(){ if (called) return; //對callback重新包裝,控制callback只執行一次 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);ft(1, 2)(console.log); // 3

這個地方的理解,方法f在執行時的參數并不是 1,2,console.log

console.log 參數在 thunkify 內部被重新包裝,成了:

function(){ if (called) return; //對callback重新包裝,控制callback只執行一次 called = true; console.log.apply(null, arguments);}

了解了 Thunk 函數之后,我們要停下來想一想,還是那句話,它的出現要解決什么問題?

是不是一定要使用 Thunk 函數?Thunk 用在什么場景下?

從前面的內容來看,其實并沒有什么用,可能概念比較新穎,但是使用起來好像并沒有太多提高。

但是沒用的話我們也不會寫這么一篇文章。

自從有了 Generator 函數,Thunk 函數現在可以用于 Generator 函數的自動流程管理。

看一下例子:

var fs = require(’fs’);var thunkify = require(’thunkify’);var readFile = thunkify(fs.readFile); var gen = function* (){ var r1 = yield readFile(’/etc/fstab’); console.log(r1.toString()); var r2 = yield readFile(’/etc/shells’); console.log(r2.toString());};

這個例子中,我們使用 yield 將執行權交給下一個協程,那么就需要有一種方法把執行權在交還給當前函數

這種方法就是 Thunk 函數,因為它可以重新包裝回調函數,我們可以自己寫包裝函數,將執行權交還給 Generator 函數。

為了對比,我們先看一下如果手動執行上面的代碼會是什么樣的:

var g = gen(); //開始執行協程var r1 = g.next(); //讀取第一個文件r1.value(function(err, data){ //讀取完成執行回調 if (err) throw err; var r2 = g.next(data); //讀取第二個文件 r2.value(function(err, data){ //讀取完成執行回調 if (err) throw err; g.next(data);//結束協程 });});

不難發現,上面的代碼其實就是將同一個回調函數傳入 value 屬性(next 執行返回 value 和 done )

我在看的時候就在想,這個value是屬性啊,為什么可以執行?還傳遞參數?

慢慢理一理:

value屬性是yield的返回值,gen中的yield返回的是一個 Thunk 函數,不是固定值。

所以可以執行value,看前面例子里的這句:ft(1, 2)(console.log);

value就等同于ft(1, 2)的返回值

傳遞的function回調等同于(console.log);

這么是不是就理解了?

Thunk 函數真正的威力,在于可以自動執行 Generator 函數。下面就是一個基于 Thunk 函數的 Generator 執行器:

function run(fn) { var gen = fn(); //自動開始協程 //對next進行包裝,形成 Thunk 函數,遍歷調用 function next(err, data) { var result = gen.next(data); if (result.done) return; result.value(next); } next(); /* 參考bootstrap的寫法改寫一下 !function next(err, data) { var result = gen.next(data); if (result.done) return; result.value(next); }(); */}run(gen);

上面的寫法很簡單吧,這么改寫之后就不需要你手動的去控制執行next的時機了

只需要執行run函數就行。但是要保證每一個yield后面都是一個 Thunk 函數,否則的話就不能自動執行了。

這一章的學習總結就結束了,我們學會了如何使用 Thunk 函數實現自動執行,但 Thunk 函數并不是 Generator 函數自動執行的唯一方案。

因為自動執行的關鍵是,必須有一種機制,自動控制 Generator 函數的流程,接收和交還程序的執行權。回調函數可以做到這一點,Promise 對象也可以做到這一點。

下一篇文章我們去看一下基于promise實現的自動執行器:co

原文:Thunk 函數的含義和用法

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關于JavaScript相關內容可查看本站專題:《JavaScript常用函數技巧匯總》、《javascript面向對象入門教程》、《JavaScript錯誤與調試技巧總結》、《JavaScript數據結構與算法技巧總結》及《JavaScript數學運算用法總結》

希望本文所述對大家JavaScript程序設計有所幫助。

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 久久久不卡国产精品一区二区 | 亚洲综合无码一区二区 | 国产精品免费aⅴ片在线观看 | 色天天综合网 | 久草小区二区三区四区网页 | 一级黄色片国产 | 青青国产成人久久激情911 | 女人牲交视频一级毛片 | 久久久四虎成人永久免费网站 | 国产高清亚洲精品26u | 一级黄色片毛片 | 欧美中日韩在线 | 寡妇影院首页亚洲图片 | 日本不卡高清中文字幕免费 | 日本不卡在线视频高清免费 | 成人三级精品视频在线观看 | 91短视频在线播放 | 草莓榴莲向日葵十八岁全微糖 | 一区二区三区在线看 | 欧美伊人久久久久久久久影院 | 日韩 欧美 亚洲 中文字幕 | 午夜dy888理论三级 | 不卡一区在线观看 | 国产在线观看青草视频 | 久久婷婷五夜综合色频 | 日韩免费视频一区二区 | 久久天堂夜夜一本婷婷麻豆 | 大学生高清一级毛片免费 | 女人被狂躁的视频免费免费看 | 国产精品99久久 | 久久综合色之久久综合 | 女猛烈无遮挡性视频免费 | 亚洲欧美一区二区三区四区 | 亚洲国产精品免费视频 | 在线观看欧洲成人免费视频 | 永久免费mv网站入口 | 在线播放国产不卡免费视频 | 一区二区三区视频免费 | 伊人网久久网 | 日本欧美国产精品第一页久久 | 国产色产综合色产在线观看视频 |