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 ...
随机推荐
- 关于MySQL集群的一些看法
作者:Gary Chen链接:https://zhuanlan.zhihu.com/p/20204156来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 市面上的招聘往往 ...
- 什么是validationQuery
validationQuery是用来验证数据库连接的查询语句,这个查询语句必须是至少返回一条数据的SELECT语句.每种数据库都有各自的验证语句,下表中收集了几种常见数据库的validationQue ...
- Python入门测试
1.比如自然数10以下能被3或者5整除的有,3,5,6和9,那么这些数字的和为23. 求能被3或者5整除的1000以内数字的和 multiple_of_threes=[] for multiple_o ...
- Jsp的基本知识
jsp页面的基本组成部分:指令,表达式,小脚本,声明,注释,静态内容. 指令元素有三种: 1.page:eg <%@ page 属性名="属性值" 属性名="属性值 ...
- 使用.net core构建分布式SAAS系统(目录)
一 前言 二 项目背景 三 项目架构-从单体应用到微服务 四 大数据量下的分库分表 五 缓存处理--进程内缓存与Redis的使用 六 使用MNS队列来流量削峰 七 百万Job的任务调度系统 八 每天1 ...
- 云计算openstack共享组件(1)——时间同步服务ntp
一.标准时间讲解 地球分为东西十二个区域,共计 24 个时区 格林威治作为全球标准时间即 (GMT 时间 ),东时区以格林威治时区进行加,而西时区则为减. 地球的轨道并非正圆,在加上自转速度逐年递减, ...
- Python进阶7--正则表达式
正则表达式*** 概述 分类 基本语法 元字符 ^ 匹配字符串的开头 $ 匹配字符串的末尾. . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符. [.. ...
- MySQL性能优化神器—explain
一.explain是什么? 简单来讲就是官方给的一个优化工具,直接在你的SQL语句前加上explain,执行整条语句,之后你就可以根据执行结果优化你的SQL啦,废话不多说,直接刚实例 测试实例 1.创 ...
- golang核心Goroutine和channel
一.Goroutine 1.介绍 goroutine简介 goroutine是go语言中最为NB的设计,也是其魅力所在,goroutine的本质是协程,是实现并行计算的核心.goroutine使用方式 ...
- ASP.net中用到的JWT
1.先通过NuGet添加JWT 2.新建一个JwtHelp类 public class JwtHelp { //私钥 web.config中配置 //"GQDstcKsx0NHjPOuXOY ...