当前位置: 首页 > 面试题库 >

为什么节点更喜欢错误优先回调?

单于奇略
2023-03-14
问题内容

节点程序员通常使用这样的范例:

let callback = function(err, data) {
  if (err) { /* do something if there was an error */ }

  /* other logic here */
};

为什么不简化该函数以仅接受一个参数(错误或响应)呢?

let callback = function(data) {
  if (isError(data)) { /* do something if there was an error */ }

  /* other logic here */  
};

似乎更简单。我唯一看到的缺点是函数不能将错误返回为它们的实际预期返回值-但我认为这是一个非常微不足道的用例。

为什么错误优先模式被认为是标准的?

编辑:的实现isError

let isError = obj => obj != null && obj instanceof Error;

另一个编辑:是否有可能我的替代方法比节点约定更方便,因为仅接受一个参数的回调也更有可能在非回调用例中重用?


问题答案:

(有关使用该问题的回调约定的npm模块,请参见下面的“更新”。)

这只是一个约定。节点也可以使用您建议的约定-除了您无法注意到的那样,成功后无法将错误对象作为预期值返回,这可能是问题也可能不是问题,具体取决于您的特定要求。

当前Node约定的问题是,有时回调可能不期望任何数据,并且回调err是它们采用的唯一参数,有时函数在成功时期望多个值-例如,参见

request(url, (err, res, data) => {
  if (err) {
    // you have error
  } else {
    // you have both res and data
  }
});

但是,即使在使用多个参数的函数中,您也可能使第一个参数成为错误,即使那样,您的样式也不会出现任何问题。

错误优先的Node风格的回调是RyanDahl最初使用的,现在已经很普遍了,并且对于使用回调的任何异步函数都是期望的。并不是说这个约定比您建议的更好或更糟,而是 有了 一个约定-
无论它是什么-
使得回调函数和采用回调函数的组合成为可能,并且异步等模块都依赖于此。

实际上,我看到了您的想法优于经典Node约定的一种方式-
不可能同时调用带有错误和定义的第一个非错误参数的回调,这对于Node样式的回调是可能的,并且有时会发生。两种约定都可能使回调函数被调用两次-这是一个问题。

但是一般而言,尤其是在Node中,JavaScript中还有另一种广泛使用的约定,即不可能同时定义错误和数据,而且不可能两次调用回调-
而不是进行回调,而是返回promise,而不是显式地检查if与Node样式回调或样式回调中的错误值一样,您可以分别添加仅获取相关数据的成功和失败回调。

所有这些样式在功能上都差不多:

nodeStyle(params, function (err, data) {
  if (err) {
    // error
  } else {
    // success
  }
};

yourStyle(params, function (data) {
  if (isError(data)) {
    // error
  } else {
    // success
  }
};

promiseStyle(params)
  .then(function (data) {
    // success
  })
  .catch(function (err) {
    // error
  });

Promise可能会更方便地满足您的需求,而Bluebird和其他工具已经为许多使用它们的工具提供了广泛的支持。

当然,我没有理由不解释为什么您不能编写一个将Node样式的回调转换为样式的回调,反之亦然的模块,并且与promise一样,就像promisify和asCallback在Bluebird中一样。如果使用回调样式对您来说更方便,那似乎确实可行。

更新资料

我刚刚在npm上发布了一个模块,您可以使用该模块来获得自己喜欢的回调样式:

  • https://www.npmjs.com/package/errc

您可以通过以下方式安装它并在您的项目中使用:

npm install errc --save

它允许您具有如下代码:

var errc = require('errc');
var fs = require('fs');

var isError = function(obj) {
  try { return obj instanceof Error; } catch(e) {}
  return false;
};

var callback = function(data) {
  if (isError(data)) {
    console.log('Error:', data.message);
  } else {
    console.log('Success:', data);
  }
};

fs.readFile('example.txt', errc(callback));

有关更多示例,请参见:

  • https://github.com/rsp/node-errc-example

我写这个模块是作为一个如何操作函数和回调以满足自己需求的示例,但是我是根据MIT许可发布的,并在npm上发布,因此您可以根据需要在实际项目中使用它。

这证明了Node的灵活性,其回调模型以及编写更高阶函数来创建自己的适合您的API的可能性。我发布它是希望它可以作为理解Node回调样式的示例



 类似资料:
  • 本文向大家介绍什么是错误优先的回调函数?相关面试题,主要包含被问及什么是错误优先的回调函数?时的应答技巧和注意事项,需要的朋友参考一下 错误优先的回调函数用于传递错误和数据。第一个参数始终应该是一个错误对象, 用于检查程序是否发生了错误。其余的参数用于传递数据。例如:   解析:这个题目的主要作用在于检查被面试者对于Node中异步操作的一些基本知识的掌握。    

  • 问题内容: 在Swing中,密码字段具有(returns )方法,而不是通常的(returns )方法。同样,我也遇到了不建议使用密码的建议。 为什么涉及密码安全性受到威胁?使用起来感觉不方便。 问题答案: 字符串是不可变的。这意味着一旦创建了,如果另一个进程可以转储内存,则除了反射之外,你将无法清除数据,然后再进行垃圾回收。 使用数组,你可以在使用完数据后显式擦除数据。你可以用任何你喜欢的东西覆

  • 问题内容: 当喜欢过? 何时以及何时使用哪种数据结构: 您想要高效的读写 应该具有更少的内存占用 尽管存在类似的问题,但它并没有突出表明应该优先选择哪个事实? 问题答案: 蜘蛛侠鲍里斯(Boris the Spider)已经概述了和之间最明显的区别-前者始终是有界的,而后者可以是无界的。 因此,如果您需要无限制的阻塞队列,或者将其用作工具箱中的最佳选择。 但是,假设您需要一个有限的阻塞队列。最后,

  • 问题内容: 我的要求是仅显示跨数据库从数据库检索的一组值。我正在使用jQuery。 问题答案: 如果满足以下任一条件,则将XML优先于JSON: 您需要消息验证 您正在使用XSLT 您的消息中包含很多标记文字 您需要与不支持JSON的环境进行互操作 当所有这些都成立时,在XML上偏爱JSON: 不需要验证消息,或者验证消息的反序列化很简单 您不是要转换邮件,也不是转换邮件的反序列​​化很简单 您的

  • 本文向大家介绍说说微信上你最喜欢的功能,以及为什么喜欢。相关面试题,主要包含被问及说说微信上你最喜欢的功能,以及为什么喜欢。时的应答技巧和注意事项,需要的朋友参考一下 喜欢: 1.小程序---节省了好多额外APP下载,大有“微信在手天下我有”的畅***;微信页下滑或搜索就可以很便捷地找到小程序的入口;与好友之间的分享也很方便。 2.订阅公众号---方便了解阅读各种感兴趣的信息与资讯;便于打发利用碎

  • 问题内容: 我有这样一行: Pylint显示警告: 这是为什么?列表理解是推荐的方法吗? 我当然可以这样重写: 而且我没有收到任何警告,但是我想知道是否为此有一个PEP? 问题答案: 皮林特(Pylint)经常谈论不该做的事情。您可以在.pylintrc文件中禁用警告。 此页面http://pylint-messages.wikidot.com/messages:w0141指示问题在于过滤器和映射