我想知道如何成功地依赖先前定义的变量来破坏回调函数。目前,我的代码看起来像是一个“回调地狱”,因为我不熟悉如何突破和构建回调的好策略。
使用大型回调函数考虑以下代码:
MongoClient.connect(
process.env.MONGODBINST,
(err, db) => {
assert.equal(null, err)
console.log("Connected successfully to database.")
app.get(
"/",
(req, res) => {
res.sendFile(path.join(__dirname + "./../public/index.html"))
}
)
app.get(
"/api/AmountIssuesOpen",
async (req, res) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
)
}
)
如何划分各个路线(app.get()
)?让我带你走过不同的情况。
const entireCallback = (err, db) => {
assert.equal(null, err)
console.log("Connected successfully to database.")
app.get(
"/",
(req, res) => {
res.sendFile(path.join(__dirname + "./../public/index.html"))
}
)
app.get(
"/api/AmountIssuesOpen",
async (req, res) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
)
}
MongoClient.connect(
process.env.MONGODBINST,
entireCallback
)
但由于第二条路线/api/AmountIssuesOpen
取决于变量db
,因此我无法将其分解为更小的函数。
const _indexRoute = (req, res) => {
res.sendFile(path.join(__dirname + "./../public/index.html"))
}
const _AmountIssuesOpenRoute = async (req, res) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
const entireCallback = (err, db) => {
assert.equal(null, err)
console.log("Connected successfully to database.")
// This works because the index Route is not dependent on `db`
app.get(
"/",
_indexRoute
)
// This does not work because `db` is undefined
app.get(
"/api/AmountIssuesOpen",
_AmountIssuesOpenRoute
)
}
MongoClient.connect(
process.env.MONGODBINST,
entireCallback
)
_AmountIssuesOpenRoute
的问题是db
未定义。如果我将db
作为参数传递,这也没有用,就像这里:
const _AmountIssuesOpenRoute = async (req, res, db) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
甚至可以打破整个app.get()
功能吗?我如何将它们放在另一个文件中并简单地转入MongoClient.connect()
回调?
const _completeIndexRoute = () => {
app.get(
"/",
(req, res) => {
res.sendFile(path.join(__dirname + "./../public/index.html"))
}
)
}
const _completeAmountIssuesOpenRoute = () => {
app.get(
"/api/AmountIssuesOpen",
async (req, res) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
)
}
const entireCallback = (err, db) => {
assert.equal(null, err)
console.log("Connected successfully to database.")
_completeIndexRoute
_competeAmountIssuesOpenRoute
}
MongoClient.connect(
process.env.MONGODBINST,
entireCallback
)
答案 0 :(得分:1)
手动添加一些承诺(可以使用async
await
实现)有点帮助。
function connect(){
return new Promise((resolve, reject) => {
MongoClient.connect(
process.env.MONGODBINST,
(err, db) => {
if (err) {
return reject(err);
}
resolve(db);
}
);
});
}
let gotDB = connect();
gotDB.then(db => {
console.log("Connected successfully to database.")
app.get(
"/",
(req, res) => {
res.sendFile(path.join(__dirname + "./../public/index.html"))
}
)
app.get(
"/api/AmountIssuesOpen",
async (req, res) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
)
}).catch(err => {
console.error("Could not connect to the database", err);
});
使用async/await
的相同代码:
async function connect(){
return new Promise((resolve, reject) => {
MongoClient.connect(
process.env.MONGODBINST,
(err, db) => {
if (err) {
return reject(err);
}
resolve(db);
}
);
});
}
try {
let db = await connect();
console.log("Connected successfully to database.")
app.get(
"/",
(req, res) => {
res.sendFile(path.join(__dirname + "./../public/index.html"))
}
)
app.get(
"/api/AmountIssuesOpen",
async (req, res) => {
const issuesOpen = await db.collection("GHISSUES")
.find({"state": "open"})
.count()
res.send({issuesOpen})
}
)
} catch {
console.error("Could not connect to the database", err);
};