当我的 React 客户端连接到服务器时:
索引.js :
var mongoAPI = require("./MongoDB/mongodb.js");
app.get("/getImages" , async function(req,res) {
var db_images = await mongoAPI.getAllImages(); // this is undefined
console.log(db_images);
res.json(db_images);
});
它转到数据库:
蒙戈德.js :
getAllImages = async () => {
await MongoClient.connect(url, function(err, db) {
if (err) {
throw err;
}
var dbo = db.db("PicturesDB");
dbo
.collection("Images")
.find({})
.toArray(function(err, result) {
if (err) {
// res.send(err);
return err;
} else {
// res.send(JSON.stringify(result));
return JSON.stringify(result);
}
});
});
};
module.exports = {
...
...
getAllImages: getAllImages
};
然而db_images
总是未定义的,即使数据正确返回(我在getAllImages
方法中使用"console.log"进行了检查(。
我的请求哪里出错了?
getAllImages
函数不返回您的值。它只返回connect
方法返回的内容。
由于您正在使用await
来调用getAllImages
函数,因此请返回一个 promise 并使用您的值解决它。
getAllImages = async () => {
return new Promise((resolve, reject) => {
MongoClient.connect(url, function(err, db) {
if (err) {
reject(err)
}
var dbo = db.db("PicturesDB");
dbo
.collection("Images")
.find({})
.toArray(function(err, result) {
if (err) {
reject(err)
} else {
resolve(JSON.stringify(result));
}
});
});
})
};
但是,最准确的模式是使用 jfriend00 在注释中指出的库的本机 promise 接口。
您当前的代码正在尝试使用await
,但您没有在数据库中使用 promise 接口。 使用 Mongodb,当您将常规回调传递给类似.connect()
或.toArray()
的东西时,它不会返回承诺,因此您的await
不会做任何有用的事情。 但是,如果您根本不传递该回调(并且使用的是数据库库的新版本(,那么它将返回您可以使用的承诺。
以下是我的建议:
getAllImages = async (url) => {
const db = await MongoClient.connect(url);
const dbo = db.db("PicturesDB");
const result = await dbo.collection("Images").find({}).toArray();
return JSON.stringify(result);
}
这会在.connect()
上使用 promise 接口并等待该接口。 如果连接失败,承诺将拒绝,await
将抛出,这将导致async
函数拒绝它已返回的承诺,以便调用方正确看到错误。
并且,请记住,当我们在async
函数中执行return JSON.stringify(result);
时,这是告诉解释器我们希望JSON.stringify(result)
成为函数已经返回的承诺的解析值(所有async
函数都返回一个承诺(。
然后,您需要在请求处理程序中进行适当的错误处理,以防getAllImages()
出现问题:
app.get("/getImages" , async function(req,res) {
try {
const db_images = await mongoAPI.getAllImages();
console.log(db_images);
res.json(db_images);
} catch(e) {
// database error
console.log(e);
res.status(500).send("database error");
}
});
我们不应该将 aysnc await 与回调混合,我只用异步 await 编写代码,mongoclient 现在返回 promise。
getAllImages = async (url) => {
const db = await MongoClient.connect(url);
if (!db)
throw "An error occurred";
var dbo = db.db("PicturesDB");
const result = await dbo.collection("Images").find({}).toArray()
if (!result)
return "error occurred";
else
return JSON.stringify(result);
}