Thunk(形实转换程序)

267 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Javascript中的thunk是指一个用于调用另一个函数的函数,没有任何参数。 换句话说,你用一个函数定义封装-函数调用,包括任何需要的任何参数,来定义这个函数的执行,那么对于这个封装函数就是一个形实转换程序,其实类似于委托层,将数据一步一步交给thunk函数,最终目标函数在thunk里拿到需要的参数,之后执行这个thunk时,最终就是调用了原始的函数。

function foo(x,y){
   return x+y
}
function fooThunk(){
  return foo(3.4)
}
console.log( fooThunk() ); // 7  

所以同步的thunk是非常简单的,但如果是异步的thunk呢?我们可以把这个狭窄的thunk定义扩展到包含让它接收一个回调函数。

function foo(x,y,cb){
   setTimeout(function(){
      cb(x+y)
   },1000)
}
function fooThunk(cb){
   foo(3,4,cb) // 这里便可以定制,类似于柯理化般
}
fooThunk(function(sum){
  console.log( sum )
})

你并不会想要手工编写thunk,所以,我们发明一个工具来做这部分的封装工作。

function thunkify(fn){ // ify - .vt
 var args = [].slice.call(arguments,1)//用于将参数转换成数组,因为参数是类数组
 return function(cb){
     args.push(cb);
     return fn.apply(null,args)
 }
}

var fooThunk = thunkify(foo,3,4)
fooThunk(function(sum){
    console.log( sum )
})

thunk在生成器与promise之间有这样的用法:

//对称:构造问题提问者

var fooThunkory = thunkify(foo)
var fooPromisory = promisify(foo)

//对称:提问

var fooThunk = fooThunkory(3,4)
var foopromise = fooPromisory(3,4)

//得到答案

fooThunk(function(err,sum){
    if(err){
        console.error(err)
    }else{
        console.log(sum)
        }
})

fooPromise(function(err,sum){
    if(err){
        console.error(err)
    }else{
        console.log(sum)
        }
})

一些thunk在不同环境的用法:

thunk函数的目的,主要是使得数据和回调分开。 -node.js

你可能会问, Thunk 函数有什么用?回答是以前确实没什么用,但是 ES6 有了 Generator 函数,Thunk 函数现在可以用于 Generator 函数的自动流程管理。 -生成器

总结: 根据封装思想以及code思想

创建的代码除了要实现功能和保持性能之外,你还应该尽可能使代码易于理解和维护。

对编程来说,抽象并不总是好事,很多时候会增加复杂度换取简洁性。

一个东西干的事情太过复杂则可以抽离出去,隐藏细节。

应该有意将这样的细节从生成器代码中抽象出来,以避免他把高层次的任务表达变得杂乱。

thunk教给我的是分层思想,虽然最终的函数调用是依次接收全部值去调用,但是我们可以同过这种思想,去分出一个个逐步包装的函数,使得每一次的功能单一,且易于维护,简介,正如那句话 用复杂性换取简洁性.

该原理同样适用于组件封装在一个组件定义很深层次的组件,最底端的组件具有通用性,将定制在中间层传递,一步一步将个性化定制最终交由底层组件实现。无线抽离。

希望写出优雅的代码