在函数中验证参数和返回错误是很常见的。
但是,在 JavaScript 回调函数中,如:
function myFunction(num, callback) {
if (typeof num !== 'number') return callback(new Error('invalid num'))
// do something else asynchronously and callback(null, result)
}
我写了很多这样的功能,但我想知道是否有潜在的危害。因为在大多数情况下,调用者假定这是一个异步函数,并且回调将在函数调用后的代码之后执行。但如果某些参数无效,该函数将立即调用回调。所以调用者必须小心处理这种情况,即意外的执行顺序。
我想听听关于这个问题的一些建议。我是否应该仔细假设所有异步回调都可以立即执行?或者我应该使用类似 setTimeout(…, 0) 的东西将同步事物转换为异步事物。或者有更好的解决方案我不知道。谢谢。
原文由 matianfu 发布,翻译遵循 CC BY-SA 4.0 许可协议
API 应记录它将调用回调同步(如
Array#sort
) 或 异步(如Promise#then
),然后 _始终遵守记录的保证_。它不应该混搭。所以是的,如果你有一个通常会异步调用回调的函数,它应该 总是 异步调用它,不管它为什么进行调用。
jQuery 中有一个很好的例子:当 jQuery 第一次添加“延迟”对象时,如果延迟已经解决,它们将 同步 调用回调,但如果没有,则异步调用。这是许多混乱和错误的根源,这也是为什么 ES2015 的承诺保证
then
和catch
回调将始终被异步调用的部分原因。如果可能并且与代码库的其余部分不冲突,请考虑使用 Promises 而不是简单的回调。 Promises 为异步操作(以及与同步操作的互操作)提供非常清晰、简单、有保证的语义和可组合性。