
callback-return
在回调之后要求 return
语句
回调模式是 JavaScript 中大多数 I/O 和事件驱动编程的核心。
function doSomething(err, callback) {
if (err) {
return callback(err);
}
callback();
}
为了防止多次调用回调,重要的是在主函数体外部触发回调时,始终使用 return
。忽略此技术通常会导致多次执行某些操作的问题。例如,在 HTTP 请求的情况下,您可能会尝试多次发送 HTTP 标头,从而导致 Node.js 抛出 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();
}
对于此规则,使用默认 ["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();
}
function bar(err, send) {
if (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
}
}
何时不使用
在某些情况下,您可能希望多次调用回调函数。在这些情况下,此规则可能会导致不正确的行为。在这些情况下,您可能希望为这些回调保留一个特殊的名称,并且不将其包含在触发警告的回调列表中。
相关规则
版本
此规则在 ESLint v1.0.0-rc-1 中引入。
延伸阅读
