【问题标题】:Returning async callback as best practice?返回异步回调作为最佳实践?
【发布时间】:2015-04-12 21:09:40
【问题描述】:

到目前为止,我从未返回任何异步回调,我只是调用了它们。我不知道(愚蠢的我!)回调调用之后的代码也会被执行。

这说明了我的意思:

var asyncFunctionNoReturn = function(callback) {
    alert('Inside asyncFunctionNoReturn');
    callback();
    alert('Still inside asyncFunctionNoReturn');
};

var asyncFunctionReturn = function(callback) {
    alert('Inside asyncFunctionReturn');
    return callback();
    alert('You will never see me! :(');
};

asyncFunctionNoReturn(function() {
    alert('I am called back!');
});

asyncFunctionReturn(function() {
    alert('I am called back!');
});

对我来说,这只有在回调调用之后有代码时才有意义:

版本 1:

...
if(err) {
    callback(err);
} else {
    callback(null, data);
}

版本 2:

...
if(err) return callback(err);
return callback(null, data);

我见过使用这两个版本。哪一个被确立为“最佳实践”?

我的猜测是版本 2:

  • 更少的代码和更少的嵌套(-> 更好的可读性?)
  • 可以更好地扩展

我希望这不是太基于意见。

【问题讨论】:

  • 我不完全同意less code and less nesting -> better readability,例如我发现版本1 更易读。我发现有时单行if-else 很难快速阅读。对不起小OT
  • 这是基于主要意见的。除了 return 的含义不同之外,就我个人而言,版本 1 可读性更好,我更喜欢它,因为如果那个地方有问题,我可以在 callback(err); 之前插入一些调试/日志信息。但这与你的问题的第一部分有什么关系,你在哪里返回一个回调来阻止下面的代码被执行?
  • 好的。我同意你的看法。括号提高了可读性,因此版本 1 对此更好。 @t.niese 在版本 1 中不返回回调。我的主要意图是询问这是否是一种不好的做法,应该始终避免。
  • 从异步函数返回一些东西(除了链接)是不常见的,可以被认为是不好的做法。 js 中从异步调用返回的唯一常见模式是支持:asyncCall(callback)asyncCall().on('error',errorCallback).on('end',endCallback').on('result',resultCallback) 或 Promise/A+ obj.doAsync().then(resultCallback)
  • 我不是在谈论返回什么,而是像我在版本 2 中那样“返回”回调调用。这有什么问题?

标签: javascript node.js asynchronous


【解决方案1】:

首先,我并不总是同意 Douglas Crockford(天哪,我说了什么?;-)),但我认为他对 if 声明的看法是正确的:它应该始终用括号写(http://javascript.crockford.com/code.html )。

我不同意你的观点:更少的代码并不意味着更好的可读性,而且对我来说,第一个版本更明显地表明了代码的意图。让我们现在拥有的(惊人的)工具担心会缩小/丑化生产代码。

不过,您仍然可以(应该?)返回回调的结果。

所以我会写:

if (err) {
    return callback(err);
} else {
    return callback(null, data);
}

【讨论】:

  • 是的,对我来说这是有道理的。可读性更好,避免回调后代码执行。
【解决方案2】:

根据环境和框架,您有不同的约定。

使用 node.js 中的 js 以及浏览器,关于异步的常见约定是:

  • 常规异步函数将可选回调作为最后一个参数
  • 回调必须看起来像 callback( err, args1, ...),在错误的情况下有 err 并且没有参数,在成功的情况下有 err null 和可选参数。
  • 回调必须始终异步调用。
  • 库/模块的异步函数应该所有行为相同,或者它们的行为应该由它们的命名doSomethingdoSomethingSyncdoSomethingAsync 决定

因此,如果您从异步函数返回某些内容,您应该对模块中的所有异步函数执行相同的操作。理想情况下使用现有约定,例如返回 EventEmitter 或 Promise。

如果行为不是预期的,通常会被认为是不好的做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2010-10-09
    • 1970-01-01
    • 2014-06-16
    • 2015-09-01
    • 1970-01-01
    相关资源
    最近更新 更多