本文深入解析JavaScript中的Thunk函数概念,阐述其作为延迟执行手段的核心机制。通过从同步幂运算到异步网络请求的代码演进,展示Thunk如何实现参数固定与回调分离。文章进一步介绍toThunk工具函数的构建方法,揭示其与Promise.then逻辑的内在联系,并探讨其在生成器配合下的应用潜力,帮助开发者掌握这一函数式编程的重要思想。
引言
本文将深入探讨Thunk机制,这是JavaScript函数式编程中关于延迟处理思想的核心组成部分之一。
什么是 Thunk ?
从编程角度简要理解,Thunk是一种用于实现延迟执行的技术手段。
举个栗子🌰🌰🌰
假设需要计算99的9次方并打印结果,你会如何编写代码?
初学者可能会直接写出一行代码:
console.log(Math.pow(99, 9)) // 913517247483640800
具备一定经验的开发者通常会将其封装为函数,以便后续复用,例如计算88的8次方或77的7次方:
const power = (base, exponent) => {
return Math.pow(base, exponent);
};
console.log(power(99, 9)); // 913517247483640800
若需求进一步扩展,可能会考虑更灵活的方案:
如果今天需要console打印结果,明天需要alert弹窗提示,后天需要handleXXX处理结果,该如何应对?
因此,可以设计一个可自定义的回调函数来处理运算结果:
代码演进
const power = (base, exponent,callback) => {
return callback(Math.pow(base, exponent))
};
const powerThunk = (callback) => {
return function () {
power(99, 9, callback);
};
};
const calculatePower = powerAsyncThunk((result) => console.log(result));
calculatePower(); // 913517247483640800
在此示例中,调用powerThunk()并不会立即执行power()运算,这种机制被称为延迟执行。
同时,powerThunk()仅需传入一个回调函数,无需再传递base 99和exponent 9这两个参数。
从某种意义上说,Thunk是一个已固定部分参数的函数。例如,power需要3个参数,而powerThunk只需1个参数,这类似于柯里化的概念。
可能有同学问了:
“我就喜欢直接修改,不喜欢封装,行吗?”
“行呀,咋不行,即使自己不做封装,你也在无时无刻地用这种封装。Promise 就是基于 Thunk。”
继续上面的例子讲:
改造成异步
上面的例子是同步的,我们改造成异步的:
const fetchCurrenciesData = (callback) => {
fetch("https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies.json")
.then(res => res.json())
.then(res => callback(res));
}
// This is an async thunk
const asyncThunk = (callback) => {
return function () {
fetchCurrenciesData(callback);
}
}
// This async thunk now returns a function that
// can be called later on to fetch data from the API.
const fetchCurrencies = asyncThunk((res) => console.log(res));
fetchCurrencies();
当我们调用 fetchCurrencies() 时,会执行 fetchCurrenciesData((res) => console.log(res))()
代码将按序执行fetch方法,然后通过.then处理为json,最后打印结果。
toThunk 工具函数
层层嵌套,我们可以编写一个toThunk工具函数:
function toThunk(asyncFn) {
return (...args) => {
return (callback) => {
asyncFn(...args, callback);
};
};
}
该函数可将任意函数处理转化为上述逻辑:
let thunk = toThunk(readFile); // readFile 是异步函数
thunk = thunk('./foo');
thunk((err, data) => /* do sth. */))
Thunk的两步执行机制:第一步传入参数,第二步传入回调函数,这正是Promise中then方法的实现思路。
Thunk还可以搭配es6生成器使用,本篇就不作展开。
JavaScript 中「Thunk」怎么理解,你 get 到了吗?
以上就是JavaScript函数式编程Thunk原理解析的详细内容,更多关于JavaScript函数式编程Thunk的资料请关注本站其它相关文章!