MongoDB回调不会抛出引用错误

Ion*_*zău 5 javascript mongodb node.js

介绍

所有人都知道,如果我们打电话,undefined.test我们将收到以下错误(两者都相同:NodeJS和Javascript):

$ node
> undefined.test
TypeError: Cannot read property 'test' of undefined
    at repl:1:11
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)
    at emitKey (readline.js:1095:12)
Run Code Online (Sandbox Code Playgroud)

那是对的!

我是怎么发现这个问题的?

通过一周我在调试以下问题时浪费了大约30分钟:脚本意外停止并且没有抛出任何错误.

我有一个urls应该是一个对象的变量:

var urls = settings.urls || {}; 
Run Code Online (Sandbox Code Playgroud)

然后在接下来的行中,我需要获取shop密钥,urls这是一个字符串:

var shop = urls.shop || "/";
Run Code Online (Sandbox Code Playgroud)

我开始添加console.log以查找变量的值:

console.log(urls);            // undefined
var shop = urls.shop || "/";
console.log("Passed");        // This isn't run.
Run Code Online (Sandbox Code Playgroud)

我的脚本中的问题是我正在重新定义一个正在制作的 urls变量urls undefined,但问题是:为什么无法读取undefined的属性"shop"没有出现在这里?因为urls真的undefined.

我们知道以下两种情况都在发生:NodeJS和Javascript:

 var a = 10;
 foo(function () {
     console.log(a); // undefined
     var a = 10;
 });
 function foo(callback) { callback(); } 
Run Code Online (Sandbox Code Playgroud)

这个问题

在调试问题之后我发现这个问题来自Mongo:如果我们调用undefined.something我们不会得到错误,那么在Mongo回调内部.

我创建了一个小脚本来演示:

var mongo = require("mongodb");

// Mongo server
var server = mongo.Server("127.0.0.1", 27017);
var db = new mongo.Db("test", server, { safe: true });

console.log("> START");

// Open database
console.log("Opening database.");
db.open(function(err, db) {
    if (err) { return console.log("Cannot open database."); }

    // get collection
    console.log("No error. Opening collection.");
    db.collection("col_one", function(err, collection) {
        if(err) { return console.log(err) }

        // do something with the collection
        console.log("No error. Finding all items from collection.");
        collection.find().toArray(function(err, items) {
            if(err) { return console.log(err) }

            console.log("No error. Items: ", items);
            console.log("The following line is: undefined.shop." +
            "It will stop the process.");
            console.log(undefined.test); // THE ERROR DOES NOT APPEAR!
            console.log("> STOP"); // this message doesn't appear.
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么不出现错误?这是什么原因?(将MongoDB源代码一起调试以找到它会很棒.)
  2. 调用时为什么停止进程undefined.something
  3. 怎么能解决这个问题?

我已经创建了一个Github存储库,您可以在其中下载我的小应用程序来演示该问题.


有趣:

如果我们添加一个try {} catch (e) {}语句,我们会发现错误,并且该过程会继续显示该STOP消息.

try {
    console.log(undefined.test);
} catch (e) {
    console.log(e);
}
Run Code Online (Sandbox Code Playgroud)

日志:

> START
Opening database.
No error. Opening collection.
No error. Finding all items from collection.
No error. Items:  []
The following line is: undefined.shop. It will stop the process.
[TypeError: Cannot read property 'test' of undefined]
> STOP
Run Code Online (Sandbox Code Playgroud)

小智 2

在github.com上查看node-mongodb-native驱动程序问题,您会发现该问题已在1.3.18版本中得到解决。但是,我测试了它,它没有按预期工作。