gpt4 book ai didi

javascript - "Call stack"用于 node.js 中的回调

转载 作者:数据小太阳 更新时间:2023-10-29 05:33:24 25 4
gpt4 key购买 nike

我习惯于用 Java 思考,我正在尝试着手研究 node.js。我的程序需要在出现问题时记录信息,我发现我必须在我的 node.js 程序中放入大量样板代码才能获得我在 Java 中免费获得的内容。

我的问题归结为:

  • 是否有更简单/非样板的方法来在回调链中获取类似堆栈的信息?和/或
  • 我是否因为未能正确掌握 node.js 而试图强制异步 node.js 更像同步 Java 而感到内疚?

Java 示例

这是一个尝试(并失败)连接到 Mongo 数据库的 noddy Java 程序: 导入 java.net.UnknownHostException;

import com.mongodb.Mongo;

public class Test {

public static void main(final String[] args) throws UnknownHostException {
final Mongo mongo = a();
}

private static Mongo a() throws UnknownHostException {
return b();
}

private static Mongo b() throws UnknownHostException {
return c();
}

private static Mongo c() throws UnknownHostException {
return new Mongo("non-existent host");
}

}

...这提供了有用的堆栈输出:

Exception in thread "main" java.net.UnknownHostException: non-existent host
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source)
at java.net.InetAddress.getAddressesFromNameService(Unknown Source)
at java.net.InetAddress.getAllByName0(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at java.net.InetAddress.getByName(Unknown Source)
at com.mongodb.ServerAddress.updateInetAddress(ServerAddress.java:204)
at com.mongodb.ServerAddress.<init>(ServerAddress.java:73)
at com.mongodb.ServerAddress.<init>(ServerAddress.java:46)
at com.mongodb.Mongo.<init>(Mongo.java:138)
at Test.c(Test.java:20)
at Test.b(Test.java:16)
at Test.a(Test.java:12)
at Test.main(Test.java:8)

(特别是,最后 4 行向我展示了在发生 Mongo 错误时我自己的代码中“发生了什么”。)

Node.js 示例

这是我在 node.js 中重写我的程序的尝试:

a(function (err, mongo) {
if (err) {
console.log("Something went wrong in main");
console.log(err);
}
});

function a(callback) {
b(function (err, mongo) {
if (err) {
console.log("Something went wrong in a()");
return callback(err);
}

return callback(null, mongo);
});
}

function b(callback) {
c(function (err, mongo) {
if (err) {
console.log("Something went wrong in b()");
return callback(err);
}

return callback(null, mongo);
});
}

function c(callback) {
var MongoClient = require('mongodb').MongoClient;
return MongoClient.connect('mongodb://non-existent host/', function (err, mongo) {
if (err) {
console.log("Something went wrong in c()");
return callback(err);
}

return callback(null, mongo);
});
}

...这给出了这个输出:

Something went wrong in c()
Something went wrong in b()
Something went wrong in a()
Something went wrong in main
[Error: failed to connect to [non-existent host:27017]]

但要获得此输出,我必须在我的程序中放入大量样板代码,随着我的程序变得越来越大并且我有一个完整的开发团队,这对警察来说会很痛苦。

我可以用另一种方式获得类似堆栈的输出吗?期望这种输出是非 Node 式的吗?

最佳答案

Promises 正是您要寻找的(将堆栈功能带回异步代码)

var Promise = require("bluebird");
var mongodb = require("mongodb");
// enable long stack traces, bluebird specific
Promise.longStackTraces();
// promisify mongodb so that it returns promises, also bluebird specific
Promise.promisifyAll(mongodb);
// raise stack limit, feature of v8/node.js
Error.stackTraceLimit = 100;


function c() {
var MongoClient = require("mongodb").MongoClient;
return MongoClient.connectAsync('mongodb://non-existent host/')
}

function b() {
return c()
}

function a() {
return b()
}

a().then(function(connection) {

});

给予:

Possibly unhandled Error: failed to connect to [non-existent host:27017]
at null.<anonymous> (/home/petka/bluebird/node_modules/mongodb/lib/mongodb/connection/server.js:546:74)
at EventEmitter.emit (events.js:106:17)
at null.<anonymous> (/home/petka/bluebird/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:150:15)
at EventEmitter.emit (events.js:98:17)
at Socket.<anonymous> (/home/petka/bluebird/node_modules/mongodb/lib/mongodb/connection/connection.js:533:10)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:830:16
From previous event:
at Function.connectAsync (eval at makeNodePromisifiedEval (/home/petka/bluebird/js/main/promisify.js:199:12), <anonymous>:7:21)
at c (/home/petka/bluebird/throwaway.js:10:28)
at b (/home/petka/bluebird/throwaway.js:14:16)
at a (/home/petka/bluebird/throwaway.js:18:16)
at Object.<anonymous> (/home/petka/bluebird/throwaway.js:21:5)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:902:3

您可以在一个地方使用 catch(如此命名是因为它像真正的 catch 语句一样工作):

 a().catch(function(e) {
//handle e
});

还添加了 bluebird 特定功能以捕获:

也支持谓词捕获,因为它只是一种方法:

 a().catch(SyntaxError, function(e) {

});

谓词可以是错误构造函数或谓词函数

 // define a predicate for IO errors
function IOError(e) {
return "code" in Object(e);
}

关于javascript - "Call stack"用于 node.js 中的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24076676/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com