日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

瀏覽:202日期: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
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美.日韩.国产.一区.二区| 欧美一级二级视频| 精品国产鲁一鲁****| 国产日韩中文在线中文字幕| 日韩精品一区二区三区中文字幕| 日韩中文一区二区| 日本不卡的三区四区五区| 亚洲精品日韩久久| 亚洲精品一级| 97久久超碰| 国产精品啊v在线| 美日韩一区二区三区| 久久精品国产99| 六月婷婷综合| 精品亚洲a∨| 国产美女高潮在线观看| 特黄特色欧美大片| 久久成人一区| 日本午夜精品久久久| 国产精品中文字幕亚洲欧美| 国产一区二区三区日韩精品| 四虎国产精品免费观看| 久久精品亚洲人成影院| 亚洲欧美视频| 日韩精品视频中文字幕| 国产精品分类| 色综合www| 天堂成人国产精品一区| 日韩二区三区四区| 国产精品一站二站| 欧美天堂视频| 亚洲免费黄色| 日韩精品一区二区三区中文| 欧美成人精品午夜一区二区| 成人三级高清视频在线看| 136国产福利精品导航网址| 在线看片日韩| 精品国产亚洲日本| 1000部精品久久久久久久久| 亚洲另类黄色| 国产不卡av一区二区| 日韩视频精品在线观看| 国产精品亚洲综合久久| 91精品亚洲| 一区二区国产在线| 久久一区欧美| 国产精品美女| 精品网站999| 久久福利影视| 久久亚洲精精品中文字幕| 亚洲网站视频| 欧美极品一区二区三区| 欧美日韩激情| 老司机精品在线| 久久亚洲风情| 国产白浆在线免费观看| 首页亚洲欧美制服丝腿| 精品日韩一区| 一区二区国产在线| 国产精品99在线观看| 日韩中文字幕1| 福利一区在线| 日韩欧美激情| 国产在线欧美| 欧美日韩亚洲一区二区三区在线| 亚洲午夜久久久久久尤物| 日本91福利区| 自由日本语亚洲人高潮| 欧美交a欧美精品喷水| 亚洲欧美日韩视频二区| 91免费精品| 婷婷精品在线| 91精品婷婷色在线观看| 国产精品对白| 日韩午夜电影| 成人小电影网站| 国产精品中文字幕制服诱惑| 欧美日韩国产综合网| 成人在线视频区| 日韩欧美久久| 日韩午夜av| 色老板在线视频一区二区| 国产精品sss在线观看av| 日韩精品一级二级| 国户精品久久久久久久久久久不卡| 免费看一区二区三区| 五月国产精品| 亚洲一区二区三区免费在线观看 | 国产精品免费精品自在线观看| 五月天久久777| 国产资源在线观看入口av| 日本亚州欧洲精品不卡| 一区在线视频观看| 在线观看精品| 国产传媒在线观看| 精品国产一区二区三区av片| 欧美日韩精品一区二区三区视频 | 亚洲精品**中文毛片| 国产精品二区影院| 欧美在线精品一区| 日韩在线卡一卡二| 狠狠色狠狠色综合日日tαg| 久久国产免费| 日韩精品欧美| 三级精品视频| 成人在线免费观看网站| 国产精品一区二区美女视频免费看 | 日本a级不卡| 久久亚洲不卡| 美女网站久久| 亚洲欧美日韩专区| 亚洲欧洲另类| 欧美日韩国产免费观看视频| 日韩一区二区三区免费播放| 国产在线不卡一区二区三区| 国产欧美日韩影院| 国产精品亚洲人成在99www| 青青草伊人久久| 国产探花在线精品一区二区| 欧美日韩网址| 国产精品2区| 欧美激情在线精品一区二区三区| 国产欧美日韩在线观看视频| 欧美日韩中文| 国产乱码精品一区二区三区四区| 91国内精品| 国产精品2区| 精品国产欧美日韩| 成人在线丰满少妇av| 超碰超碰人人人人精品| 91精品啪在线观看国产18| 国模 一区 二区 三区| 中文日韩在线| 婷婷久久免费视频| 国产九一精品| 国产a亚洲精品| 久久久久久久久久久9不雅视频| 亚洲国产专区校园欧美| 亚洲欧美激情诱惑| 日韩精品福利一区二区三区| 国产精品日韩精品在线播放| 成人综合一区| 黑丝美女一区二区| 久久一二三区| 欧美亚洲三级| 水蜜桃久久夜色精品一区| 久久久久国产精品一区三寸| 91久久黄色| 91国内精品| 91一区二区三区四区| 成人免费电影网址| 免费日韩精品中文字幕视频在线| 丝袜美腿一区二区三区| 日韩精品电影一区亚洲| 欧美激情久久久久久久久久久| 国产不卡av一区二区| 久久人人99| 亚洲视频国产精品| 国产精品第一| 亚洲精品88| 另类亚洲自拍| 国产精品videossex久久发布| 国产精品精品国产一区二区| 91精品国产调教在线观看| 亚洲天堂免费| 精品一区二区三区亚洲| 久久精品亚洲人成影院| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产精品sm| 欧美性感美女一区二区| 日韩精品中文字幕吗一区二区| 精品免费视频| 久久一二三区| 精品国产鲁一鲁****| 久久精品99久久无色码中文字幕| 一区二区三区国产在线| 美女视频黄免费的久久| 久久婷婷激情| 欧美日韩视频免费看| 午夜精品成人av| 中文字幕视频精品一区二区三区 | 国产亚洲观看| 久久久久久久久久久9不雅视频| 日韩在线a电影| 欧美国产美女| 日本一区二区三区视频在线看| bbw在线视频| 自拍自偷一区二区三区| 精品久久中文| 最新国产精品久久久| 日韩伦理在线一区| 日本亚洲不卡| 亚洲91久久| 国产精品一区二区三区av| 精品一区欧美| 美女视频黄免费的久久| 中文字幕视频精品一区二区三区| 激情国产在线| 国产欧美在线| 欧美专区18|