thunkify这种函数其实就是python的decorator方式,对目标方法进行一步步的wrap,但是这种方式和generator结合起来就会威力无穷了,实现自动异步功能。

thunkify使用一般分为三步,这里以fs.readFile这个非阻塞函数为例.

1.用thunkify  wrap要调用的目标函数,这里是fs.readFile。

2.wrap目标函数 的普通参数,这里就是fs.readFile的文件名称

3.wrap目标函数 操作结束时的毁掉函数,这里是fs.readFile的 callback参数

node.js中的非阻塞api调用都是这个路子,如fs.readFile(fileName,callback);

thunkify注解

第一步:fn为fs.readFile
function thunkify(fn){
assert('function' == typeof fn, 'function required');

第二部:arguments为fs.readFile(filename,callback)的文件名称:filename
return function(){
var args = new Array(arguments.length);
var ctx = this; for(var i = 0; i < args.length; ++i) {
args[i] = arguments[i];
}

第三步:done为fs.readLine(filename,callback)中的callback
return function(done){
var called; args.push(function(){
if (called) return;
called = true;
done.apply(null, arguments);
}); try {
fn.apply(ctx, args);
} catch (err) {
done(err);
}
}
}
};

fs.readFile借用thunkify:

1.var readFile=thunkify(fs.readFile)

2.var fn=readFile('filename') 到此结束,还没真正开始调用系统api,一切都只是处于闭包缓存状态

3.fn(function callback(err,data){}) 到这里才开始真正的开始调用os api 读取文件数据了。

下面是从es 6 标准入门的一个例子改过来的:thunkif和generator 配合,自动完成非阻塞的读取文件。

var thunkify=require('thunkify');
var fs=require('fs');
var readFile=thunkify(fs.readFile); var generator=function* (){
for(var i=0;i<arguments.length;i++){
console.log('file: %s',arguments[i]);
var r1=yield readFile(arguments[i]); //yield thunkify 最内部的 function (done){} 函数
console.log('r1: %s',r1);
}
} function rungenerator(generator){
//文件名称
var args=[];
for(var i=1;i<arguments.length;i++){
args.push(arguments[i]);
}
//生成generator实例
var gen= generator.apply(null,args);
function next(err,data){
if(data){
console.log('data:',data.toString());
}
//执行跳到 generator中去
var result=gen.next('abc');
if(result.done) {return;}
//console.log('result: %s',result.value);
result.value(next);//真正的调用,next作为回调
}
next();
} rungenerator(generator,'1.js','2.js','3,js')

另外:python和javascript中的generator的差别还是很大的,python中的generator是个跛脚的东西,generator不能嵌套调用,没有实现彻底的实现,导致它的执行路线只能被封闭在同一个generator中。js中没有这个问题。

node的 thunkify模块说明的更多相关文章

  1. node之path模块

    node之path模块 原文链接 //引用该模块 var path = require("path"); 1.路径解析,得到规范化的路径格式 对window系统,目录分隔为'', ...

  2. 运用node的文件系统模块批量修改文件名

      如果我们需要大批量修改一个文件中的名称,比如,删除文件名中的副本时,就可以借助node的文件系统模块,快捷快速的完成. 首先建立一个js文件(changeName.js),代码如下: // 引入f ...

  3. thunkify 模块

    function thunkify(fn){ assert('function' == typeof fn, 'function required'); return function(){ var ...

  4. Node.js的模块载入方式与机制

    Node.js中模块可以通过文件路径或名字获取模块的引用.模块的引用会映射到一个js文件路径,除非它是一个Node内置模块.Node的内置模块公开了一些常用的API给开发者,并且它们在Node进程开始 ...

  5. Node.js Web模块

    什么是Web服务器? Web服务器是处理由HTTP客户端发送的,如web浏览器的HTTP请求的软件应用程序,并返回响应于客户端网页. Web服务器通常伴随着图片,样式表和脚本的HTML文档. 大多数W ...

  6. Node.js工具模块

    在Node.js的模块库中提供实用的模块数量. 这些模块都是很常见的,并同时开发基于任何节点的应用程序频繁使用. S.N. 模块的名称和说明 1 OS Module提供基本的操作系统相关的实用功能 2 ...

  7. node.js基础模块http、网页分析工具cherrio实现爬虫

    node.js基础模块http.网页分析工具cherrio实现爬虫 一.前言      说是爬虫初探,其实并没有用到爬虫相关第三方类库,主要用了node.js基础模块http.网页分析工具cherri ...

  8. Node.js:模块

    概要:本篇博客主要介绍node.js的模块 1.创建模块 在node.js中创建一个模块非常简单,因为一个文件就是一个模块.我们只需要明白如何从其他文件中获取这个模块.Node.js提供了 expor ...

  9. node.js之模块

    node.js之模块 1.自定义模块的设置 加载自定义模块利用require: eg: require('./custom_module.js') 2.从模块外部访问模块内的成员 2.1使用expor ...

随机推荐

  1. ubuntu与登录有关的log配置信息

    1. 所有sudo, sshd, sftp登录的信息都在auth.log中. 2. pam的配置是在/etc/pam.conf与/etc/pam.d中,在文件夹pam.d对cron, sudo,ssh ...

  2. golang调用c++文件

    简要步骤: 1,将c++ 的方法提取到头文件.h中( ) 2,编译cc(c++)文件为动态链接库so文件 3,将头文件放入include目录 .so放入lib目录 4,go程序中指定 CFLAGS 和 ...

  3. Qt字符串类——3.字符串的转换

    (1)QString::toInt()函数将字符串转换为整型数值,类似的函数还有toDouble().toFloat().toLong().toLongLong()等.下面举个例子说明其用法: QSt ...

  4. [原创]解决net-speeder与pptp不兼容的问题

    解决net-speeder与pptp不兼容的问题 终于受不了很多玩意儿都被墙了,每次FQ费半天劲,浪费时间,于是在搬瓦工搞了个VPS,年付19美元,挺便宜的,赶紧的VPN搭起,优化走起. VPN搭建很 ...

  5. 4. Decision Tree

    一般的,一颗决策树包含一个根结点.若干内部结点和若干叶结点:叶节点对应于决策结果,其他每个结点则对应于一个属性测试:每个结点包含的样本集合根据属性测试的结果被划分到子结点中:根结点包含样本全集.从根结 ...

  6. windows下面配置apache+http

    一.apache安装 下载并安装apache_2.2.9-win32-x86-openssl-0.9.8h-r2.msi(见附件),找到apache安装目录(C:\Program Files (x86 ...

  7. dubbo源码分析6-telnet方式的管理实现

    dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...

  8. cssSelector定位笔记1

    cssSelector定位方法:1.使用class属性定位元素:driver.findElement(By.cssSelector("input.login"));即可以先指定一个 ...

  9. C#字符串的方法

    static void Main(string[] args) { StrMethod(); } public static void StrMethod() { string myString = ...

  10. 【js跨域】js实现跨域访问的几种方式

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...