资讯专栏INFORMATION COLUMN

js的Thunk函数的含义

史占广 / 1707人阅读

摘要:在语言中,函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。它的源码主要多了一个检查机制,变量确保回调函数只运行一次请看下面的例子。

Thunck函数的含义

编译器的传名调用实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做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语言是传值调用,它的Thunck函数含义有所不同。在JavaScript语言中,Thunk函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。

//正常版本的readFile(多参数版本)
fs.readFile(fileName,callback);
//Thunk版本的readFile(单参数版本);
var Thunk = function(fileName){
    return function(callback){
        return fs.readFile(fileName,callback);
    };
};
var readFileThunk = Thunk(fileName);
readFileThunk(callback);

上面代码中,fs模块的readFile方法是一个错参数函数,两个参数分别为文件名和回调函数。经过转换器处理,它变成了一个但参数函数,只接受回调函数作为参数。这个单参数版本,就叫做Thunk函数。
任何函数,只要参数有回调函数,就能写成Thunk函数的形式。下面是一个简单的Thunk函数转换器。

//ES5版本
var Thunk = function(fn){
    return function(){
        var args = Array.Prototype.slice.call(arguments);
        return function(callback){
            args.push(callback);
            return fn.apply(this,args);
        }
    };
};
//ES6版本
const Thunk = function(fn){
    return function(...args){
        return function(callback){
            return fn.call(this,...args,callback);
        }
    };
};
//使用上面的转化器,生生fs.readFile的Thunk函数。
var readFileThunk = Thunk(fs.readFile);
readFileThunk(fileA)(callback)
Thunkify模块

生产环境的转换器,建议使用Thunkify模块。
首先是安装。

$ npm install thunkify

使用方式如下。

var thunkify = require("thunkify");
var fs = require("fs");
var read = thunkify(fs.readFile);
read("package.json")(function(err,str){
    //...
})

Thunkify的源码与上面的简单的转换器非常像。

function thunkfiy(fn){
    return function(){
        var args = new Array(arguments.length);
        var ctx = this;
        for(var i=0;i

它的源码主要多了一个检查机制,变量called确保回调函数只运行一次,请看下面的例子。

function f(a,b,callback){
    var sum = a+b;
    callback(sum);
    callback(sum);
}
var ft = thunkify(f);
var print = console.log.bind(console);
ft(1,2)(print);
//上面代码中,由于thunkify只允许回调函数执行一次,所以只输出一行结果。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99611.html

相关文章

  • callback

    摘要:前言入门阮一峰另类的实现同级别的另外一个函数。该事件系统允许代码定义应用程序的特定事件,该事件可以传递自定义参数,自定义参数包含订阅者所需要的值。其目的是避免订阅者和发布者产生依赖关系。状态转变不可逆。方法必须返回一个。 callback 前言 ECMAScript 6入门(阮一峰) showImg(https://segmentfault.com/img/remote/1460000...

    tianren124 评论0 收藏0
  • Thunk深入解析

    摘要:捕抓信息,并且出错时,传递给回调函数回调函数应该只调用一次。总结在学习一个概念或者一个模块时,测试代码加深你对知识的理解和掌握。 一步步打造thunkify 本文的思路: 学习thunk相关知识,主要参考阮一峰的介绍 一步步实现thunkify模块,并且使用测试用例来完善我们的代码,打造出一个健壮的模块 1. 诞生背景 Thunk函数的诞生是源于一个编译器设计的问题:求值策略,即函...

    xi4oh4o 评论0 收藏0
  • Node.js 异步异闻录

    摘要:的异步完成整个异步环节的有事件循环观察者请求对象以及线程池。执行回调组装好请求对象送入线程池等待执行,实际上是完成了异步的第一部分,回调通知是第二部分。异步编程是首个将异步大规模带到应用层面的平台。 showImg(https://segmentfault.com/img/remote/1460000011303472); 本文首发在个人博客:http://muyunyun.cn/po...

    zzbo 评论0 收藏0
  • 浅谈async·await

    摘要:在语言中,函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。为什么里面必须使用函数呢,因为我们需要确保传入的值只有一个,利用其回调函数,来进行递归自动控制函数的流程,接收和交还程序的执行权 前言 这篇文章主要是梳理一下自己对阮一峰大神写的关于async/await文章,有写得不对的地方以及理解得不对的地方,各位大佬请指错! 对比 简单对比传统异步,...

    Magicer 评论0 收藏0
  • 理解通过thunk函数自动执行generator函数

    摘要:总结执行方法本质上相当于注册一个回调函数,而函数结合函数就是一种更直观的注册回调函数的方式。函数负责异步执行交出执行权,而函数负责注册回调返回执行权,执行下一步,两者结合从而自动执行函数。 今天又看了一遍阮一峰老师的《Thunk 函数的含义和用法》,这里整理一下自己的理解: 在 JavaScript 语言中,Thunk 函数替换的不是表达式,而是多参数函数,将其替换成单参数的版本,且只...

    int64 评论0 收藏0

发表评论

0条评论

史占广

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<