thunkify重构
发布于 10 年前 作者 booxood 8504 次浏览 最后一次编辑是 8 年前

这个标题是不是太响亮了?!

刚看了@suqian 关于connect与koa的帖子,发现有用到一个require('thunkify-wrap');,于是好奇,找到了TJ的thunkify模块,thunkify-wrap没仔细去看,应该是对thunkify的功能进行了扩充吧。

对thunkify的那几十行代码看了估计都有一个小时吧,总算是明白了,IQ捉急啊。。。

觉得可以稍微改下,也许可以更好懂一点。

function thunkify(fn){
  return function(){
    var args = [].slice.call(arguments);
    var results;
    var cb;

    function callback(){
      if (results && cb) {
        cb.apply(this, results);
      }
    }

    args.push(function(){
      results = arguments;
      callback.apply(this);
    });

    fn.apply(this, args);

    return function(fn){
      cb = fn;
      callback.apply(this);
    }
  }
};

主要两点改动,一是把两次判断是否执行cb合并到了一起,二是去掉对called的判断。 对于第二点,TJ在已发的PR回复说 ”the called check is to prevent double callbacks“ 但不会有两次callback都成功的吧,只有一次callback会成功执行。

本准备直接发PR的,想想先让各位大大过目一下,看看这样是否合适。

19 回复

提取了个方法, 不错, 可以跑下test试试

其实不需要这种东西~~~ 只要 yield xxx.bind(null, yyyy), 即可,

比如 fs ,

yield fs.readFile.bind(null, yyyy)

嗯 有空看看有什么不同

yyyy 是什么?回调还是参数?

@xieren58 将函数用thunkify封装下是为了配合 co 用,你这样可以吗?

@booxood 可以,你自己可以试试

你写的这个完全有可能调用两次callback

@Dengshen 不会把,这样修改之后是可以跑通Test Case的,你举个栗子?

确实有可能跑两次,TJ的那个对此做了判断的,你这个没有做这个判断 一是回调触发了,二是回调函数刚好绑定了 这是原来的代码要做两次判断的原因

楼下说的对

@hwoarangzk @Dengshen

一是回调触发了,二是回调函数刚好绑定了 确实是这样,所以TJ的代码在这两次要执行之前都做了判断。

一是把两次判断是否执行cb合并到了一起,二是去掉对called的判断。 我是把判断放到了callback,去掉了called判断并不是没有判断。TJ的两次判断if (cb && !called) if (results && !called), 我合并成了if (results && cb) ,通过判断 result 和 cb 都已经有了才执行 cb.apply(this, results);

下面是TJ当时的版本

function thunkify(fn){
  return function(){
    var args = [].slice.call(arguments);
    var results;
    var called;
    var cb;

    args.push(function(){
      results = arguments;

      if (cb && !called) {
        called = true;
        cb.apply(this, results);
      }
    });

    fn.apply(this, args);

    return function(fn){
      cb = fn;

      if (results && !called) {
        called = true;
        fn.apply(this, results);
      }
    }
  }

又挖坟了?

@xadillax 不算太深把。。。

回到顶部