Thunk
Thunk
https://en.wikipedia.org/wiki/Thunk
In computer programming, a thunk is a subroutine used to inject an additional calculation into another subroutine. Thunks are primarily used to delay a calculation until its result is needed, or toinsert operations at the beginning or end of the other subroutine. They have a variety of other applications in compiler code generation and modular programming.
JS DEMO
// 'hypot' is a binary function
const hypot = (x, y) => Math.sqrt(x * x + y * y); // 'thunk' is a function that takes no arguments and, when invoked, performs a potentially expensive
// operation (computing a square root, in this example) and/or causes some side-effect to occur
const thunk = () => hypot(3, 4); // the thunk can then be passed around...
doSomethingWithThunk(thunk); // ...or evaluated
thunk(); // === 5
词典
https://cn.bing.com/dict/search?q=thunk&FORM=BDVSP2&qpvt=Thunk
- 〔计〕形实替换程序;计算机的形式实在转换程序
- 网络形实转换程序;替换程式;出现在互操作中
结合上面的例子我们理解为, 将函数的参数提前进行绑定, 在需要的时候调用。
绑定的过程, 就是将 实际参数 绑定到 形式参数上, 可以对应到 形实替换的意思。
阮大解释
http://www.ruanyifeng.com/blog/2015/05/thunk.html
编译器的"传名调用"实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数。
function f(m){
return m * 2;
} f(x + 5); // 等同于 var thunk = function () {
return x + 5;
}; function f(thunk){
return thunk() * 2;
}
上面代码中,函数 f 的参数 x + 5 被一个函数替换了。凡是用到原参数的地方,对 Thunk 函数求值即可。
这就是 Thunk 函数的定义,它是"传名调用"的一种实现策略,用来替换某个表达式。
JavaScript 语言是传值调用,它的 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);
};
};
上面代码中,fs 模块的 readFile 方法是一个多参数函数,两个参数分别为文件名和回调函数。经过转换器处理,它变成了一个单参数函数,只接受回调函数作为参数。这个单参数版本,就叫做 Thunk 函数。
Thunk实现
原理:
var Thunk = function(fn){
return function (){
var args = Array.prototype.slice.call(arguments);
return function (callback){
args.push(callback);
return fn.apply(this, args);
}
};
};
var readFileThunk = Thunk(fs.readFile);
readFileThunk(fileA)(callback);
Node thunkify
https://github.com/tj/node-thunkify
var thunkify = require('thunkify');
var fs = require('fs');
var read = thunkify(fs.readFile);
read('package.json', 'utf8')(function(err, str){
});
类似概念
curry
https://www.sitepoint.com/currying-in-functional-javascript/
var greetCurried = function(greeting) {
return function(name) {
console.log(greeting + ", " + name);
};
};
var greetHello = greetCurried("Hello");
greetHello("Heidi"); //"Hello, Heidi"
greetHello("Eddie"); //"Hello, Eddie"
使得函数更加可读和弹性
More Readable And More Flexible
One of the advantages touted for functional JavaScript is shorter, tighter code that gets right to the point in the fewest lines possible, and with less repetition. Sometimes this can come at the expense of readability; until you’re familiar with the way the functional programming works, code written in this way can be harder to read and understand.
If you’ve come across the term currying before, but never knew what it meant, you can be forgiven for thinking of it as some exotic, spicy technique that you didn’t need to bother about. But currying is actually a very simple concept, and it addresses some familiar problems when dealing with function arguments, while opening up a range of flexible options for the developer.
https://www.npmjs.com/package/curry
var curry = require('curry');//-- creating a curried function is pretty//-- straight forward:var add = curry(function(a, b){ return a + b });//-- it can be called like normal:add(1, 2) //= 3//-- or, if you miss off any arguments,//-- a new funtion that expects all (or some) of//-- the remaining arguments will be created:var add1 = add(1);add1(2) //= 3;
bind
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
bind()方法创建一个新的函数,在调用时设置this关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
var module = {
x: 42,
getX: function() {
return this.x;
}
}var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefinedvar boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
Thunk的更多相关文章
- react+redux教程(一)connect、applyMiddleware、thunk、webpackHotMiddleware
今天,我们通过解读官方示例代码(counter)的方式来学习react+redux. 例子 这个例子是官方的例子,计数器程序.前两个按钮是加减,第三个是如果当前数字是奇数则加一,第四个按钮是异步加一( ...
- JavaScript 中的 Thunk 函数
参数的求值策略: var x = 1; function f(m){ return m * 2; } f(x + 5); // x +5 在何时运算? 1.传值调用: var x = 1; funct ...
- C++ 通过Thunk在WNDPROC中访问this指针实现细节
本文代码使用了一些C++11特性,需要编译器支持.本文仅讨论x86_64平台的相关实现,x86平台理论上只需修改 thunk 相关机器码即可. THUNK的原理参见之前的一篇博文<C++ 通过T ...
- C++ 通过Thunk在WNDPROC中访问this指针
本文基本只讨论原理,具体实现请参见后续文章<C++ 通过Thunk在WNDPROC中访问this指针实现细节> 当注册窗口类时,WNDCLASSEX结构的lpfnWndProc成员应设置为 ...
- 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)
我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...
- c++ THUNK技术
这里想说的是:代码中的关键点为用指令jmp pFunc跳转到你想要运行的函数pFunc. 指令"jmp xxxx"占5个字节,代码中用了个一字节对齐的结构体struct Thunk ...
- 转: ES6异步编程:Thunk函数的含义与用法
转: ES6异步编程:Thunk函数的含义与用法 参数的求值策略 Thunk函数早在上个世纪60年代就诞生了. 那时,编程语言刚刚起步,计算机学家还在研究,编译器怎么写比较好.一个争论的焦点是&quo ...
- thunk的主要用法
主要用法目前用的多的就三种; thunk.all 并发 thunk.sql 同步 thunk.race 最先返回的进入结果输出 前两个返回的结果都是数组,最后一个返回的是对象: thunk的链式调用没 ...
- thunk技术
Thunk : 将一段机器码对应的字节保存在一个连续内存结构里, 然后将其指针强制转换成函数. 即用作函数来执行,通常用来将对象的成员函数作为回调函数. #include "stdafx.h ...
- C++函数调用的反汇编过程及Thunk应用
x86汇编基础知识 1. 汇编常用寄存器 esp,(Extended stack pointer)栈顶指针.因为x86的栈内存是向下扩展的,因此当push入栈时,esp–.pop出栈时,esp++.e ...
随机推荐
- 【原】无脑操作:HTML5 + CSS + JavaScript实现比赛排程
1.背景:朋友请帮忙做一个比赛排程软件 2.需求: ① 比赛人数未知,可以通过文本文件读取参赛人员名称: ② 对参赛人员随机分组,一组两人,两两PK,如果是奇数人数,某一个参赛人员成为幸运儿自动晋级: ...
- mysql表与表之间数据的转移
1.相同表结构 INSERT INTO table1 SELECT * FROM table2; 2.不同表结构 INSERT INTO table1(filed1,...,filedn) SELEC ...
- SpringBoot文档
一.Spring Boot 入门 1.Hello World探究 1.POM文件 1.父项目 <parent> <groupId>org.springframework.b ...
- 是时候选择一款富文本编辑器了(wangEditor)
需要一款富文本编辑器,当然不能自己造轮子.本来想使用cnblog也在用的TinyMCE,名气大,功能全.但是发现TinyMCE从4.0开始,不再支持直接下载.所以还是决定选用wangEditor.遗憾 ...
- Django Template(模板)
一.模板组成 组成:HTML代码 + 逻辑控制代码 二.逻辑控制代码的组成 1.变量 语法格式 : {{ name }} # 使用双大括号来引用变量 1.Template和Context对象(不推荐使 ...
- 多线程手写Future模式
future模式 在进行耗时操作的时候,线程直接阻塞,我们需要优化这样的代码,让他再启动一个线程,不阻塞.可以执行下面的代码. 这个时候我们就用到了未来者模式 future设计类 只有一个方法 pub ...
- 记录学习antd design pro dva的过程,主要记错, 多图预警,如有理解偏差,忘指出,多谢!
首要问题: 如何增加菜单项 答案: 在router.config中添加路由,在locales语言国际化增加选项 问题1: 答案1: 问题2: 这个要修改state,正确写法 存在的疑惑:为什么不能直接 ...
- jeecg入门操作—一对多表单开发
一.创建主表 创建订单主表(torder_main) 二.创建附表客户信息表(torder_customer) 设置附表页面外键不可见 设置附表外键 三.创建附表机票 信息表(torder_tic ...
- 菜鸟学IT之python网页爬取初体验
作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2881 1. 简单说明爬虫原理 爬虫简单来说就是通过程序模拟浏览器放松请求站 ...
- 美化ubuntu18.04,并安装搜狗输入法
目录 美化Ubuntu 下载主题和图标文件 下载GNOME3 美化过程 安装输入法 下载并安装搜狗输入法 安装fcitx框架 安装过程 美化Ubuntu 下载主题和图标文件 下载地址:https:// ...