javascript - Node.js 中不必要的回调使用?

标签 javascript node.js asynchronous callback nonblocking

我正在学习 Node.js,并且掌握了有关异步非阻塞 I/O 的大部分基础知识。我的问题是,当函数本身不是异步时,创建带有回调的函数有什么意义。即使您正在创建的函数调用了异步函数,我也找不到您使用回调的原因。我在我正在查看的 Node.js 代码中经常看到这种情况。

例如,发送 HTTP 请求并返回请求的解析输出的函数:

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);
  });
}

第一个带有回调的函数通过回调返回结果,而第二个函数只是正常返回结果。

最佳答案

本来想写评论,但是有点太长了。

您问了几个问题。为了解决评论者提出的非常正确的观点,第二个示例将不起作用,并且正如 @Hawkings 更清楚地指出的那样,无法(通过您的代码)捕获结果。它不起作用,因为第二个示例中的 return 正在调用您正在创建的匿名函数(实际回调被传递给 request),并在内部深处返回其结果请求函数。此外,在您的示例中,控制权早在调用 return JSON.parse() 行之前就已经返回到 withoutCallback 的调用者,并且如所写的, foo = withoutCallback(...) 将导致 foo 未定义。

如果您查看使用回调的库的代码,您将看到它们是如何被调用的,并且可能更容易理解为什么这不起作用。 (尽管我建议查看一个比 request 更简单的库 - 如果您对 Node 相当陌生,我认为您会发现 request 库有点令人困惑)。

但是,就您所说的情况而言,您的问题是(您的示例中未说明):“我的问题是,当函数本身不是异步的时,创建带有回调的函数有什么意义[?]”

在这种特定情况下没有多大意义,除非a)您想在未来证明它,以防它由于添加的功能而变得异步,或者b)您希望有一个通用接口(interface),其中其他实现将是异步的。使用浏览器示例只是因为它很容易想到,如果您正在实现一个通用的基本数据存储解决方案,其中一个实现将使用 LocalStorage (同步),但其他实现可能使用 IndexedDB 或远程调用(均为异步) -您仍然希望使用回调编写 LocalStorage 实现,以便可以轻松地在实现之间切换。

如果您不喜欢回调风格,请考虑学习使用和使用利用其他技术或语言功能来处理异步性的库,包括 Promises、Generators 或在适用情况下的 EventEmitters。我个人是 Promise 的忠实粉丝。话虽如此,在您了解回调的方式和原因之前,我不会建议其中任何一个。

关于javascript - Node.js 中不必要的回调使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33182119/

相关文章:

javascript - 在 JavaScript 实例上编写单个原型(prototype)与使用多个原型(prototype)之间的区别?只是风格?

javascript - 当鼠标悬停时更改背景图像

javascript - 变量在脚本标签中不可用

javascript - 在 ESlint 中执行 "linebreak-style"规则有多重要?我可以把它关掉吗?

python - 带超时的异步子进程

javascript - $.getJSON 返回值到变量

javascript - 将多个 div 元素映射到数组中

javascript - Nodejs 从数组表达流

node.js - 错误: Cannot find module 'ieee754' - while running 'lb' command in Loopback js

javascript - 为什么javascript方法最后执行?