JavaScript 中「Thunk」怎么理解?

简介: JavaScript 中「Thunk」怎么理解?

image.png

降低阅读负担,启发创作心智,轻松学习 JavaScript 技巧,日拱一卒,jym,冲~


本篇带来 Thunk 理解,这也是本瓜最津津乐道的 JS 函数式编程中延迟处理的思想核心之一!


什么是 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 = powerThunk((result) => console.log(result));
calculatePower(); // 913517247483640800


在这个例子中,调用powerThunk() 并不会马上执行 power() 运算,这就是所谓的延迟执行。


并且 powerThunk() 只用再传一个回调函数进去就行了,不用再传 base 99 和 exponent 9 这两个参数了。


在某种意义上来讲,thunk 也是一个已经固定某些参数的一个函数,上例中 power 要传 3 个参数,而 powerThunk 只用传一个参数就行了。这感觉就有点像柯里化。

可能有同学问了:


“我就喜欢直接修改,不喜欢封装,行吗?”

“行呀,咋不行,即使自己不做封装,你也在无时无刻地用这种封装。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 工具函数:


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 到了吗?


相关文章
|
7月前
|
自然语言处理 JavaScript 前端开发
探索JavaScript中的闭包:理解其原理与实际应用
探索JavaScript中的闭包:理解其原理与实际应用
66 0
|
2月前
|
缓存 JavaScript 前端开发
深入了解JavaScript的闭包:概念与应用
【10月更文挑战第8天】深入了解JavaScript的闭包:概念与应用
|
4月前
|
JavaScript 前端开发 Java
JavaScript中的闭包概念讲解
闭包是指函数内部嵌套另一个函数,并且内部函数引用了外部函数的数据(如变量或函数)。这样的内部函数被称为闭包。以示例代码为例,`fn1` 中有两个闭包函数 `fn2` 和 `fn3`,它们都可以访问并修改 `fn1` 中的变量 `a`。
24 1
|
7月前
|
自然语言处理 JavaScript 前端开发
闭包对于javascript中有什么作用
JavaScript中的闭包有多种用途,如数据封装和私有化、函数工厂及保持状态。闭包能创建私有变量和函数,防止外部访问,实现清晰的代码接口。
|
7月前
|
存储 Web App开发 自然语言处理
聊一聊 JavaScript 中的作用域和闭包
起因是最近了解JS执行上下文的时候,发现很多书籍和资料,包括《JavaScript高级程序设计》、《JavaScript权威指南》和网上的一些博客专栏,都是从 ES3 角度来谈执行上下文,用ES6规范解读的比较少,所以想从ES6的角度看一下执行上下文。 下面我尝试用[ECMAScript 6规范](https://262.ecma-international.org/6.0)文档,来聊聊执行上下文
139 0
聊一聊 JavaScript 中的作用域和闭包
|
自然语言处理 JavaScript 前端开发
【深度剖析】JavaScript中块级作用域与函数作用域
【深度剖析】JavaScript中块级作用域与函数作用域
|
存储 自然语言处理 JavaScript
如何理解JavaScript中的执行上下文
如何理解JavaScript中的执行上下文
80 0
|
自然语言处理 JavaScript 前端开发
JavaScript中的闭包原理及应用
对于 JavaScript 开发者而言,闭包是一个非常重要的概念,也是面试中常常会被问到的问题。本篇博客将会详细介绍 JavaScript 中的闭包原理及其应用,并提供相关的代码示例和注释。
214 0
|
存储 自然语言处理 前端开发
重学前端 18 # JavaScript的闭包和执行上下文
重学前端 18 # JavaScript的闭包和执行上下文
118 0
重学前端 18 # JavaScript的闭包和执行上下文
|
JavaScript 前端开发 Java
JavaScript闭包从概念、原理到应用
闭包的概念:有权访问另一个函数作用域中的变量的函数;一般情况就是在一个函数中包含另一个函数。
123 0