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 ...
随机推荐
- Asp.Net中virtual、override理解
virtual关键字用于指定属性或方法在派生类中重写.默认情况下,派生类从其基类继承属性和方法,如果继承的属性或方法需要在派生类中有不同的行为,则可以重写它,即可以在派生类中定义该属性或方法的新实现, ...
- 好程序员web前端分享javascript关联数组用法总结
好程序员web前端分享javascript关联数组用法总结,有需要的朋友可以参考下. Hash关联数组定义 代码如下 // 定义空数组 myhash = { } // 直接定义数组 myhash = ...
- python day07
数据类型之间的相互转换 1.字符串转换成数字类型 判断哪些可以转换成数字型可以参考下面例题: # 判断实现将所有能转换为数字类型的字符串都转换为对应类型的数字# int: '10' = > 10 ...
- 身边有个漂亮的java女程序员是什么体验?
程序员都是一些追求完美的人.女程序员细致认真,不仅能写代码而且注释详尽清晰.能做好单元测试BUG最少.能写标准规范的设计文件不会对不上模块编号也不会少了类或接口说明,提交代码不会忘记写LOG,不会和测 ...
- .NET和PHP程序员如何通过技术快速变现
刚开始写博客不足之处望大家多多指点,少一些质疑多一些帮助,我们就能成为朋友. 上一篇:<.NET程序员我是如何通过一个产品在2年内买车买房>有很多同为程序员的小伙伴们给我留言,从整体的留言 ...
- Education CodeForces Round 63 Div.2
A. Reverse a Substring 代码: #include <bits/stdc++.h> using namespace std; int N; string s; int ...
- Win10 + MySQL + Tableu + PPT + 可视化方案
1. 官网下MySQL 2. 解压到硬盘, 新建my.ini文件: [mysql] ; 设置mysql客户端默认字符集 default-character-set=utf8 [mysqld] ;设置3 ...
- mysql排序,同样的sql,mysql 每次查询结果顺序不一致
某天项目中写了一句排序sql,但是发现每次执行的结果都不同,就是排序顺序不一样. select * from table_tmp order by printStatus asc,dealTime d ...
- Django3 Django 路由分发,反向解析,2.0版本的path
urls配置像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行. 1.简 ...
- SpringBoot+AOP整合
SpringBoot+AOP整合 https://blog.csdn.net/lmb55/article/details/82470388 https://www.cnblogs.com/onlyma ...