Nodejs thunkify重构

Nodejs thunkify重构

提取了个方法, 不错, 可以跑下test试试

12 回复

Nodejs Thunkify 重构

在Node.js中,thunkify 是一个非常有用的工具,它可以帮助我们将传统的回调函数风格的异步操作转换为更易于使用的Thunk函数。Thunk函数是一种特殊的函数,它接受一个参数(通常是回调函数),并在内部调用该回调函数来处理结果。

什么是Thunkify?

thunkify 的核心思想是将异步操作包装成一个函数,这个函数返回一个Thunk对象。当这个Thunk对象被调用时,会执行原始的异步操作,并通过回调函数传递结果。

示例代码

假设我们有一个读取文件的异步操作:

const fs = require('fs');

// 原始的异步函数
function readFile(filename, callback) {
    fs.readFile(filename, 'utf8', (err, data) => {
        if (err) return callback(err);
        callback(null, data);
    });
}

// 使用 thunkify 包装
const thunkify = require('thunkify');
const readFileThunk = thunkify(readFile);

// 使用 thunkify 重构后的代码
async function main() {
    try {
        const data = await readFileThunk('./example.txt');
        console.log(data);
    } catch (err) {
        console.error(err);
    }
}

main();

在这个例子中,我们首先定义了一个原始的异步函数 readFile,它接受一个文件名和一个回调函数。然后我们使用 thunkify 包装这个函数,生成一个新的Thunk函数 readFileThunk。最后,在 main 函数中,我们使用 await 关键字等待 readFileThunk 的结果,这样就可以以同步的方式处理异步操作了。

为什么使用Thunkify?

  1. 简化代码:Thunkify使得异步代码更加简洁,避免了嵌套回调地狱。
  2. 更好的错误处理:使用 try...catch 可以更容易地捕获和处理错误。
  3. 可组合性:Thunk函数可以很容易地与其他函数组合,实现更复杂的逻辑。

通过这种方式,我们可以更方便地处理异步操作,提高代码的可读性和可维护性。希望这个例子能帮助你理解如何在Node.js中使用 thunkify 进行重构。


其实不需要这种东西~~~ 只要 yield xxx.bind(null, yyyy), 即可,

比如 fs ,

yield fs.readFile.bind(null, yyyy)

嗯 有空看看有什么不同

yyyy 是什么?回调还是参数?

你写的这个完全有可能调用两次callback

确实有可能跑两次,TJ的那个对此做了判断的,你这个没有做这个判断 一是回调触发了,二是回调函数刚好绑定了 这是原来的代码要做两次判断的原因

楼下说的对

下面是TJ当时的版本

function thunkify(fn){
  return function(){
    var args = [].slice.call(arguments);
    var results;
    var called;
    var cb;
args.push(function(){
  results = arguments;

  if (cb && !called) {
    called = true;
    cb.apply(this, results);
  }
});

fn.apply(this, args);

return function(fn){
  cb = fn;

  if (results && !called) {
    called = true;
    fn.apply(this, results);
  }
}

}

又挖坟了?

当然可以!下面是一个关于如何使用 thunkify 对一个 Node.js 异步方法进行重构的示例。假设我们有一个异步的文件读取方法,原始的方法是使用回调的方式实现的:

原始版本(使用回调)

const fs = require('fs');

function readFileCallback(filename, callback) {
    fs.readFile(filename, 'utf-8', (err, data) => {
        if (err) return callback(err);
        callback(null, data);
    });
}

// 使用示例
readFileCallback('example.txt', (err, data) => {
    if (err) return console.error(err);
    console.log(data);
});

重构版本(使用 thunkify)

我们可以使用 thunkify 将这个方法转换为返回一个可调用的 thunk 函数的形式,这样就可以更方便地与 Promises 或其他异步控制流库一起使用。

首先,需要安装 thunkify

npm install thunkify

然后,我们可以使用 thunkify 进行重构:

const thunkify = require('thunkify');
const fs = require('fs');

// 使用 thunkify 包装 fs.readFile 方法
const readFileThunk = thunkify(fs.readFile);

function* readFileGenerator(filename) {
    try {
        const data = yield readFileThunk(filename, 'utf-8');
        console.log(data);
    } catch (err) {
        console.error(err);
    }
}

// 使用 co 库来运行生成器函数
const co = require('co');
co(readFileGenerator('example.txt'));

在这个例子中,我们使用了 thunkify 包将 fs.readFile 方法转换为一个 thunk 函数,该函数返回一个函数,可以被 yield 关键字调用。通过配合 co 库,我们可以更方便地使用生成器函数处理异步操作。

如果你对 co 库不熟悉,可以查看其文档,了解如何更好地使用生成器函数来管理异步流程。

回到顶部