# 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
语句之前。此规则根据被调用函数的名称决定什么是回调。
# 选项
该规则采用单个选项 - 可能的回调名称数组 - 其中可能包括对象方法。默认回调名称为 callback
、cb
、next
。
# 默认回调名称
此规则使用默认 ["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
}
}
# 何时不使用
在某些情况下,您可能希望多次调用回调函数。在这些情况下,此规则可能会导致不正确的行为。在这些情况下,您可能希望为这些回调保留一个特殊名称,而不是将其包含在触发警告的回调列表中。