本文已参与「新人创作礼」活动,一起开启掘金创作之路。
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教给我的是分层思想,虽然最终的函数调用是依次接收全部值去调用,但是我们可以同过这种思想,去分出一个个逐步包装的函数,使得每一次的功能单一,且易于维护,简介,正如那句话 用复杂性换取简洁性.
该原理同样适用于组件封装在一个组件定义很深层次的组件,最底端的组件具有通用性,将定制在中间层传递,一步一步将个性化定制最终交由底层组件实现。无线抽离。
希望写出优雅的代码