# callback-return

此规则在 ESLint v7.0.0 中已弃用。请使用 eslint-plugin-node 中的相应规则。

回调模式是 JavaScript 中大多数 I/O 和事件驱动编程的核心。

function doSomething(err, callback) {
    if (err) {
        return callback(err);
    }
    callback();
}

为了防止多次调用回调,在主函数体之外触发回调时,return 很重要。忽略此技术通常会导致您多次执行某项操作的问题。例如,在 HTTP 请求的情况下,您可能会尝试多次发送 HTTP 标头,从而导致 Node.js 向 throw 发送 Can't render headers after they are sent to the client. 错误。

# 规则详情

此规则旨在确保在主功能块之外使用的回调始终是 return 语句的一部分或紧接在 return 语句之前。此规则根据被调用函数的名称决定什么是回调。

# 选项

该规则采用单个选项 - 可能的回调名称数组 - 其中可能包括对象方法。默认回调名称为 callbackcbnext

# 默认回调名称

此规则使用默认 ["callback", "cb", "next"] 选项的错误代码示例:

/*eslint callback-return: "error"*/

function foo(err, callback) {
    if (err) {
        callback(err);
    }
    callback();
}

此规则使用默认 ["callback", "cb", "next"] 选项的正确代码示例:

/*eslint callback-return: "error"*/

function foo(err, callback) {
    if (err) {
        return callback(err);
    }
    callback();
}

# 提供的回调名称

带有选项 ["done", "send.error", "send.success"] 的此规则的错误代码示例:

/*eslint callback-return: ["error", ["done", "send.error", "send.success"]]*/

function foo(err, done) {
    if (err) {
        done(err);
    }
    done();
}

function bar(err, send) {
    if (err) {
        send.error(err);
    }
    send.success();
}

带有选项 ["done", "send.error", "send.success"] 的此规则的正确代码示例:

/*eslint callback-return: ["error", ["done", "send.error", "send.success"]]*/

function foo(err, done) {
    if (err) {
        return done(err);
    }
    done();
}

function bar(err, send) {
    if (err) {
        return send.error(err);
    }
    send.success();
}

# 已知限制

因为通过静态分析很难理解程序的含义,所以这条规则有局限性:

  • 假阴性 当此规则报告正确的代码,但程序多次调用回调(这是不正确的行为)
  • 误报 当此规则报告不正确的代码,但程序只调用了一次回调(这是正确的行为)

# 通过引用传递回调

如果是函数的参数(例如setTimeout),该规则的静态分析不会检测到程序调用回调。

此规则报告正确代码时的误报示例:

/*eslint callback-return: "error"*/

function foo(err, callback) {
    if (err) {
        setTimeout(callback, 0); // this is bad, but WILL NOT warn
    }
    callback();
}

# 在嵌套函数中触发回调

此规则的静态分析未检测到程序从嵌套函数或立即调用函数表达式 (IIFE) 中调用回调。

此规则报告正确代码时的误报示例:

/*eslint callback-return: "error"*/

function foo(err, callback) {
    if (err) {
        process.nextTick(function() {
            return callback(); // this is bad, but WILL NOT warn
        });
    }
    callback();
}

# if/else 语句

该规则的静态分析没有检测到程序在if语句的每个分支中只调用了一次回调。

此规则报告错误代码时的误报示例:

/*eslint callback-return: "error"*/

function foo(err, callback) {
    if (err) {
        callback(err); // this is fine, but WILL warn
    } else {
        callback();    // this is fine, but WILL warn
    }
}

# 何时不使用

在某些情况下,您可能希望多次调用回调函数。在这些情况下,此规则可能会导致不正确的行为。在这些情况下,您可能希望为这些回调保留一个特殊名称,而不是将其包含在触发警告的回调列表中。

Last Updated: 5/13/2023, 8:55:38 PM