什么是 thunk

在 redux-thunk 中,为什么会有 thunk 这个词,原来大有来头
更新于: 2021-12-19 12:57:28

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

https://daveceddia.com/what-is-a-thunk/

https://juejin.cn/post/6987325687661068318