node.js 中不必要的回调使用?
Unnecessary callback usage in node.js?
我正在学习 node.js,我掌握了关于异步非阻塞的大部分基础知识 I/O。我的问题是,当函数本身不是异步时,创建带有回调的函数有什么意义。即使您正在创建的函数调用了异步函数,我也找不到您使用回调的原因。我在查看的 node.js 代码中经常看到这一点。
例如,发送 HTTP 请求和 returns 请求的已解析输出的函数:
function withCallback(url, callback) {
request(url, function(err, response, html) {
if (err)
callback(err, null);
callback(null, JSON.parse(html));
});
}
function withoutCallback(url) {
request(url, function(err, response, html) {
if (err)
throw err;
return JSON.parse(html);
});
}
带有回调的第一个函数 returns 通过回调返回结果,而第二个函数只是 returns 它正常。
本来打算写评论的,但是写的有点太长了。
你问了几个问题。为了解决评论者提出的非常正确的观点,第二个示例将不起作用,并且正如@Hawkings 更清楚地指出的那样,无法捕获结果(通过您的代码)。它不会工作,因为第二个示例中的 return
正在调用您正在创建的匿名函数(传递给 request
的实际回调)并在 request
深处返回其结果功能。此外,在您的示例中,控制权在调用 return JSON.parse()
行之前就已经返回给 withoutCallback
的调用者,并且如所写, foo = withoutCallback(...)
将导致 foo
被未定义。
如果您查看使用回调的库的代码,您将看到这些回调是如何被调用的,并且它可能更有意义为什么这行不通。 (虽然我建议看一个比 request 更简单的库——如果你是 node 的新手,我想你会发现 request 库有点令人困惑)。
但是,如果您陈述的问题是(示例中未说明):"My question is what's the point of creating a function with callbacks when the function itself isn't asynchronous[?]"
在那种特定情况下没有太多意义,除非 a) 你想在未来证明它,以防它可能因为添加的功能而变得异步,或者 b) 你想要一个通用接口,在这个接口中其他实现将是异步的.使用浏览器示例只是因为它很容易让人想到,如果您正在实现一个通用的基本数据存储解决方案,其中一个实现将使用 LocalStorage(同步),而其他可能使用 IndexedDB 或远程调用(均为异步)-您仍然希望使用回调编写 LocalStorage 实现,以便您可以轻松地在实现之间切换。
如果您不喜欢回调样式,请考虑学习使用并使用利用其他技术或语言功能来处理异步性的库,包括 Promises、Generators 或适用情况下的 EventEmitters。我个人是 Promises 的忠实粉丝。话虽如此,在您了解回调的方式和原因之前,我不会建议其中任何一个。
我正在学习 node.js,我掌握了关于异步非阻塞的大部分基础知识 I/O。我的问题是,当函数本身不是异步时,创建带有回调的函数有什么意义。即使您正在创建的函数调用了异步函数,我也找不到您使用回调的原因。我在查看的 node.js 代码中经常看到这一点。
例如,发送 HTTP 请求和 returns 请求的已解析输出的函数:
function withCallback(url, callback) {
request(url, function(err, response, html) {
if (err)
callback(err, null);
callback(null, JSON.parse(html));
});
}
function withoutCallback(url) {
request(url, function(err, response, html) {
if (err)
throw err;
return JSON.parse(html);
});
}
带有回调的第一个函数 returns 通过回调返回结果,而第二个函数只是 returns 它正常。
本来打算写评论的,但是写的有点太长了。
你问了几个问题。为了解决评论者提出的非常正确的观点,第二个示例将不起作用,并且正如@Hawkings 更清楚地指出的那样,无法捕获结果(通过您的代码)。它不会工作,因为第二个示例中的 return
正在调用您正在创建的匿名函数(传递给 request
的实际回调)并在 request
深处返回其结果功能。此外,在您的示例中,控制权在调用 return JSON.parse()
行之前就已经返回给 withoutCallback
的调用者,并且如所写, foo = withoutCallback(...)
将导致 foo
被未定义。
如果您查看使用回调的库的代码,您将看到这些回调是如何被调用的,并且它可能更有意义为什么这行不通。 (虽然我建议看一个比 request 更简单的库——如果你是 node 的新手,我想你会发现 request 库有点令人困惑)。
但是,如果您陈述的问题是(示例中未说明):"My question is what's the point of creating a function with callbacks when the function itself isn't asynchronous[?]"
在那种特定情况下没有太多意义,除非 a) 你想在未来证明它,以防它可能因为添加的功能而变得异步,或者 b) 你想要一个通用接口,在这个接口中其他实现将是异步的.使用浏览器示例只是因为它很容易让人想到,如果您正在实现一个通用的基本数据存储解决方案,其中一个实现将使用 LocalStorage(同步),而其他可能使用 IndexedDB 或远程调用(均为异步)-您仍然希望使用回调编写 LocalStorage 实现,以便您可以轻松地在实现之间切换。
如果您不喜欢回调样式,请考虑学习使用并使用利用其他技术或语言功能来处理异步性的库,包括 Promises、Generators 或适用情况下的 EventEmitters。我个人是 Promises 的忠实粉丝。话虽如此,在您了解回调的方式和原因之前,我不会建议其中任何一个。