纵有疾风起
人生不言弃

Thunk&&函数柯里化

compose

函数做为另一个函数的参数时,因为函数式参数,所以先执行作为参数的函数。

函数柯里化

接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数。并且返回接受余下的参数而且返回结果的新函数的技术。
柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理批特定的需求。这增加了函数的适用性,但同时也降低了函数的适用范围。

Thunk 函数的含义

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

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

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

任何函数,只要参数有回调函数,就能写成 Thunk 函数的形式。下面是一个简单的 Thunk 函数转换器。

var Thunk = function(fn){  return function (){    var args = Array.prototype.slice.call(arguments);    return function (callback){      args.push(callback);      return fn.apply(this, args);    }  };};

使用上面的转换器,生成 fs.readFile 的 Thunk 函数。

var readFileThunk = Thunk(fs.readFile);readFileThunk(fileA)(callback);

redux中间件

让我们可以介入数据从 action 到 reducer 之间的传递过程,从而改变数据流,实现如异步、数据过滤、日志上报等功能。

加载中间件有两个核心的方法: createStore 和 applyMiddleware ,接下来我们就从源码剖析,看 redux 中间件的运行原理到底是怎么样的。

import compose from './compose'export default function applyMiddleware(...middlewares) {  return (createStore) => (reducer, preloadedState, enhancer) => {    var store = createStore(reducer, preloadedState, enhancer)    var dispatch = store.dispatch    var chain = []    var middlewareAPI = {      getState: store.getState,      dispatch: (action) => dispatch(action)    }    chain = middlewares.map(middleware => middleware(middlewareAPI))    dispatch = compose(...chain)(store.dispatch)    return {      ...store,      dispatch    }  }}

实现applyMiddleware&thunk

export function applyMiddleware(middleWare){       return createStore=>(...args)=>{        // 生成createStore,...agr就是reducer        const store = createStore(...args)        let dispatch = store.dispatch        const midApi = {            getState : store.getState,            dispatch : (...args)=>dispatch(...args)        }        // 把原生的dispatch拿出来,给到middleWare        dispatch = middleWare(midApi)(store.dispatch)        return {            ...store,            dispatch        }    }}----const thunk = ({dispatch,getState})=>next=>action=>{    // 如果是函数,执行以下,参数是dispatch和getState    if(typeof action == 'function'){        return action(dispatch,getState)    }    // 默认,什么都没干    return next(action)}

1、enhancer(createStore)(reducer, preloadedState) 执行的时候,参数 createStore 给了第一层匿名函数,因为我们的目的是要对 createStore 进行修饰。而 reducer, preloadedState 两个参数给了第二层匿名函数。

文章转载于:https://www.jianshu.com/p/195123fca27a

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » Thunk&&函数柯里化
分享到: 生成海报

评论 抢沙发

评论前必须登录!

立即登录