- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
Node 程序员通常使用这样的范例:
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;
另一个编辑:我的替代方法是否可能比 Node 约定更方便,因为只接受一个参数的回调更有可能被非回调用例重用?
最佳答案
(有关使用问题中的回调约定的 npm 模块,请参阅下面的“更新”。)
这只是一个约定。 Node 也可以使用您建议的约定 - 除了您无法将错误对象作为您注意到的成功的预期值返回,这可能是也可能不是问题,具体取决于您的特定要求.
当前 Node 约定的问题是,有时回调可能不期望任何数据,而 err
是它们采用的唯一参数,有时函数期望成功时有多个值 -例如看
request(url, (err, res, data) => {
if (err) {
// you have error
} else {
// you have both res and data
}
});
见 this answer有关上述代码的完整示例。
但是即使在采用多个参数的函数中,您也可以将第一个参数设置为错误,即使那样我也看不到您的样式有任何问题。
错误优先的 Node 样式回调是 Ryan Dahl 最初使用的,现在它非常普遍,并且适用于任何接受回调的异步函数。并不是说这个约定比你建议的更好或更糟,而是拥有一个约定——不管它是什么——使得回调和回调函数的组合成为可能,以及像 async 这样的模块依靠它。
事实上,我看到您的想法优于经典 Node 约定的一种方式 - 不可能在定义错误和第一个非错误参数的情况下调用回调,这对于 Node 样式回调是可能的,有时可以发生。不过,这两种约定都可能会调用两次回调 - 这是一个问题。
但是在 JavaScript 中还有另一个广泛使用的约定,特别是在 Node 中,它不可能同时定义错误和数据,而且不可能两次调用回调 - 不是接受回调,而是返回一个 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和其他人。
你可以看到一些其他的答案,我解释了回调和 promise 之间的区别以及如何更详细地一起使用,这在这种情况下可能对你有所帮助:
当然,我看不出为什么你不能编写一个模块来将 Node 风格的回调转换为你的风格回调,反之亦然,promise 也是如此,就像 promisify和 asCallback在 bluebird 工作。如果使用您的回调样式对您来说更方便的话,这似乎是可行的。
我刚刚在 npm 上发布了一个模块,您可以使用它来设置您喜欢的回调样式:
您可以安装它并在您的项目中使用:
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));
更多示例见:
我编写了这个模块作为如何操作函数和回调以满足您的需求的示例,但我在 MIT 许可下发布它并发布在 npm 上,因此您可以根据需要在实际项目中使用它。
这展示了 Node 的灵 active 、它的回调模型以及编写高阶函数以创建适合您需求的自己的 API 的可能性。我发布它是希望它可以作为理解 Node 回调样式的示例。
关于node.js - 为什么 Node 更喜欢错误优先回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40511513/
我用运行 Node node --debug app OR node --debug-brk app 它有反应 debugger listening on port 5858 Express serv
这个问题在这里已经有了答案: What is the difference between (int *i) and (int* i) in context of both C and C++? [
我有一个应用程序,它通过消息队列将数据库写入命令分派(dispatch)给工作人员(数量非常大),因此无法保证它们的接收顺序。 我有两个 Node ,例如“Account”和“Media”。在此假设的
有没有办法在调用 ts-node 时将选项传递给 Node ?我正在尝试在 Node 中使用一个实验性功能,如果它能与 ts-node 一起使用,那就太好了。 这就是我目前正在做的事情: ts-nod
我有一个容器化的Node应用程序,它在DigitalOcean服务器上运行。当我更新服务器上的应用程序时,该应用程序必须关闭一小段时间。为了能够更新应用程序并避免停机,我目前正在阅读零停机时间部署/蓝
我正在编写一个 Node.js 应用程序。我正在使用 request 和 Cheerio 加载一组 URL 并获取该网站的大量信息,现在假设我想要获取的只是标题: var urls = {"url_1
如果不弹出以下错误,我无法安装任何 Node.js 模块。错误代码引用package.json文件。如果知道为什么会发生这种情况,我们将不胜感激。 最佳答案 这些不是错误,它们只是警告。一切都应该如此
如果我运行(从我的项目目录中): supervisor javascripts/index.js 我得到:/usr/bin/env: Node :没有这样的文件或目录 如果我运行: node java
我已遵循使用 Node-Inspector 的所有步骤 但是当我打开应用程序时,我在控制台上看不到任何脚本或日志。 我的应用程序在端口 4000 上运行。我认为唯一可能发生冲突的是端口 8080 上的
我在android中使用rxjava2,有时会遇到这样的问题: Observable.fromArray( // maybe a list about photo url in SD
我目前正在使用 Node 光纤来编写同步服务器端代码。我主要通过 try-catch block 进行错误处理,但外部库或其他小部分异步代码中总是有可能发生错误。我正在考虑使用新的域功能来尝试将这些错
看起来node-debug是node-inspector周围的一个shell?分别什么时候应该使用? 最佳答案 如果您安装node-debug,您只能访问node-debug命令。 如果您安装node
我目前正在代理后面工作,该代理不允许我执行此命令的 HTTP GET 请求阶段: Node node-sass/scripts/build.js 请求阶段: gyp http GET https://
听说node js可以用在服务端。我以前用过jsp。 jsp页面内部的java代码对客户端是不可见的。如果 Node js 只是 javascript,那么它如何对客户端不可见? 最佳答案 首先,No
我正在为 Node native 插件从 node-waf 构建迁移到 node-gyp 构建系统。 node-gyp 说它支持多个目标版本,但我在使用 node-gyp 时找不到如何指定目标 Nod
给定一个 $node ,我正在尝试在以下两种输出该 $node 的方式之间做出决定。 要么 $output = theme('node', $node); 或 node_build_content($
如果package.json中的窗口A打开一个新窗口B,node-main如何访问它?这是我的代码: package.json { "main": "index.html",
我试图在我的 xml 中的特定节点 ( ) 之前插入一个注释节点。这是它的方法: function test(xmlResponse) { var parser = new DOMParse
我正在尝试做npm install wrtc使用 Node 版本 16.14.0 但这还没有完成。它在给npm error code 1所以我试图将 Node 版本更改为以前的 lts 14.19.0
当我在 Visual Studio 中运行 Node.js 应用程序时,我收到以下消息:DeprecationWarning: 'node --debug' 和 'node --debug-brk'
我是一名优秀的程序员,十分优秀!