2017-10-12 75 views
1

我对JavaScript回调感到困惑。我不明白他们的逻辑和他们为什么工作。下面的代码是正确的,但它怎么会是?Node.js回调混淆 - MongoDB的findOne()的第三个参数:为什么允许这样做?

app.get('db').collection("foo").findOne({ 
    bar: req.query.baz 
}, { 
    _id: 0 
}, (err, doc) => { 
    if (err) { 
    res.json({ 
     status: 503, 
     message: "DB fault" 
    }); 
    return; 
    } 
    res.json({ 
    status: 200, 
    qux: doc 
    }); 
}); 

这是MongoDB的findOne()的定义:

db.collection.findOne(查询,投影)

但在上面的代码中,多于两个参数被传递,所以我会期待一个错误。

+0

首先,在JS中,如果您传递的函数多于它所需的参数,则不会出现错误。通常他们只是被忽略。 MongoDB曾经使用这个第三个参数传递一个回调函数来处理异步结果。我知道他们在开始流行时也开始实施Promises作为替代方案。我猜测他们完全切换到Promises,而旧的回调语法现在已被弃用。但这只是一个猜测。 – Thomas

+1

这个逻辑似乎仍然存在,虽然它不再被记录。 [检查GitHub上的源代码](https://github.com/mongodb/node-mongodb-native/blob/2.2/lib/collection.js#L1396)。回调是什么,这会让你感到困惑? – Thomas

+0

Aaaah,我不知道第三个参数的存在,我认为它是一些特殊类型的JS或Node.js逻辑,或者即使函数没有定义回调函数,它仍然可以用于回调不知何故......但现在我明白了,谢谢!我还是新来的异步编程和节点,这让我感到困惑。 – tom

回答

1

额外的参数永远不会在JavaScript中引发错误。同样在像C这样的语言中,他们最多只会产生编译时错误。这是完全自然的行为,并且您使用的是错误的文档。正确的是,here

findOne(query, options, callback) -> {Promise} 

由于API是支持的承诺,实际上你可以通过链接一个接着一个使用省略回调现代JavaScript的异步/等待

const value = await findOne(query, options) 

有许多差异到API。例如。你也可以像在Python中那样异步调用Cursor的迭代器。然而,记录的方式是最古老,也是最快捷的做事方式。

+0

感谢您对Promises的使用。我将决定我更喜欢哪种格式。 – tom