什么是 thunk
在 redux-thunk 中,为什么会有 thunk 这个词,原来大有来头
Thunk 函数的含义
编译器的传名调用实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做Thunk函数。
thunk 与 currying的异别
- 首先 两者都是符合函数式编程理念的
- thunk 是延迟计算,他将多参数改为单参数版本,且只接收回调函数,或是最后一个参数必需是回调函数
- 而 currying 却无该限制。
- thunk 更多是想把执行函数和回调函数拆分开,让开发者在写异步代码的时候可以更专注于执行函数的逻辑。
thunk 的示例
const thunkify = function (fn) {
return function (url) {
return function (callback) {
return fn(url, callback)
}
}
}
function ajax(url, cb) {
$.ajax({
url: url,
success: cb
});
}
const getData = thunkify(ajax)
const req1 = getData('https://jsonplaceholder.typicode.com/todos/1')
req1(function (data) {
console.log(data)
}) // req1 接收一个回调函数为参数
多次串行请求,2种不同的实现——传统写法
ajax('./api/1', function (data1) {
//传统定义的逻辑一般写在回调里
ajax('./api/2', function (data2) {
ajax('./api/3', function (data3) {});
});
});
多次串行请求,2种不同的实现——thunk写法
var getData = thunkify(ajax);
// 执行函数
var req1 = getData('https://jsonplaceholder.typicode.com/todos/1');
var req2 = getData('https://jsonplaceholder.typicode.com/todos/2');
var req3 = getData('https://jsonplaceholder.typicode.com/todos/3');
// 回调函数
req1(function (data1) {
req2(function (data2) {
req3(function (data3) {});
});
});
多次串行请求,2种不同的实现——thunk写法 + generator 函数
// 创建 Generator
const gen = function* () {
const data1 = yield getData("https://jsonplaceholder.typicode.com/todos/1");
console.log(data1); // 获取数据后自定义操作
const data2 = yield getData("https://jsonplaceholder.typicode.com/todos/2");
console.log(data2);
const data3 = yield getData("https://jsonplaceholder.typicode.com/todos/3");
console.log(data3);
};
// 手动执行 Generator
var g = gen();
var data1 = g.next();
// 执行回调函数传回数据
data1.value(function (data) {
const data2 = g.next(data);
data2.value(function (data2) {
const data3 = g.next(data2);
data3.value(function (data3) {
g.next(data3);
});
});
});
参考:
https://www.ruanyifeng.com/blog/2015/05/thunk.html