代码片段来自node.js 和mongoDB CRUD 应用程序。 Github repo for full code.代码工作正常,但不确定我的结构以及 Promise 和 async wait 的使用是否是不好的做法。
handlers._newbies = {};
handlers._newbies.post = (parsedReq, res) => {
const newbie = JSON.parse(parsedReq.payload);
databaseCalls.create(newbie)
.then((result) => {
res.writeHead(200,{'Content-Type' : 'application/json'});
const resultToString = JSON.stringify(result.ops[0]);
res.write(resultToString);
res.end();
})
.catch(err => console.log(err));
};
const databaseCalls = {};
databaseCalls.create = (newbie) => {
return new Promise(async (resolve, reject) => {
try {
const client = await MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true });
console.log("Connected correctly to server");
const db = client.db('Noob-List');
const result = await db.collection('newbies').insertOne(newbie);
client.close();
resolve(result);
} catch(err) {
console.log(err);
}
});
};
当 Node 服务器收到带有 JSON 有效负载的 POST 请求时,它会调用 handlers._newbies.post 处理程序,该处理程序获取有效负载并将其传递给
const newbie = JSON.parse(parsedReq.payload);
databaseCalls.create(newbie)
打电话。我希望此数据库调用返回一个包含 db.collection('newbies').insertOne(newbie);
结果的 promise
称呼。我在仅返回 insertOne 返回的 promise 时遇到了麻烦,因为返回后我无法调用 client.close();
.
也许我在这里所做的一切都很好,但我没有在网上找到任何关于使用其中的 promise 创建 promise 的内容。感谢您抽出宝贵的时间让我知道我的问题中有哪些不清楚的地方。
最佳答案
将现有的 Promise 包装在手动创建的 Promise 中被认为是一种反模式,因为没有理由这样做,而且它会产生许多错误的机会,特别是在错误处理中。
并且,就您的情况而言,您有几个错误处理问题。
- 如果您的数据库代码中的任何位置出现错误,您永远不会解决或拒绝您正在创建的 promise 。这是反模式的典型问题。
- 如果打开数据库后出现错误,则不要关闭数据库
- 您不会向调用者返回错误。
以下是如何在没有反模式且没有上述问题的情况下执行 .create()
函数:
databaseCalls.create = async function(newbie) {
let client;
try {
client = await MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true });
console.log("Connected correctly to server");
const db = client.db('Noob-List');
return db.collection('newbies').insertOne(newbie);
} catch(err) {
// log error, but still reject the promise
console.log(err);
throw err;
} finally {
// clean up any open database
if (client) {
client.close();
}
}
}
然后,您可以像这样使用它:
databaseCalls.create(something).then(result => {
console.log("succeeded");'
}).catch(err => {
console.log(err);
});
仅供引用,我还修改了其他一些内容:
- 即使在错误情况下,数据库连接也会关闭
- 该函数返回一个 Promise,该 Promise 通过
.insertOne()
的结果进行解析(如果那里有有意义的结果) - 如果出现错误,则返回的 Promise 会因该错误而被拒绝
与您的 promise 问题不是特别相关,但您通常不希望在每个操作上打开和关闭数据库连接。您可以使用一个持久连接,也可以创建一个连接池,您可以从池中获取一个连接,然后在完成后将其放回池中(大多数数据库都具有用于服务器端工作的此类功能)。
关于javascript - 使用异步函数调用创建新的 Promise 是不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50554373/