Javascript 如何根据前面的变量来分解/导出回调函数 如何根据前面的变量来分解/导出回调函数

Javascript 如何根据前面的变量来分解/导出回调函数 如何根据前面的变量来分解/导出回调函数,javascript,express,ecmascript-6,Javascript,Express,Ecmascript 6,我想知道如何能够成功地突破依赖于先前定义的变量的回调函数。目前,我的代码看起来像一个“回调地狱”,因为我不熟悉关于如何中断和构造回调的好策略 先决条件 考虑以下使用大型回调函数的代码: MongoClient.connect( process.env.MONGODBINST, (err, db) => { assert.equal(null, err) console.log("Connected successfully to databa

我想知道如何能够成功地突破依赖于先前定义的变量的回调函数。目前,我的代码看起来像一个“回调地狱”,因为我不熟悉关于如何中断和构造回调的好策略

先决条件 考虑以下使用大型回调函数的代码:

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()
)?让我带你经历不同的情况

情景1:中断整个回调(这很有效) 情况2:进一步爆发-这不起作用 但我不可能将其分解成更小的函数,因为第二条路径
/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
)
\u AmountIssuesOpenRoute
的问题是
db
未定义。如果我将
db
作为参数传入,也没有什么帮助,如下所示:

const _AmountIssuesOpenRoute = async (req, res, db) => {
    const issuesOpen = await db.collection("GHISSUES")
                                .find({"state": "open"})
                                .count()
    res.send({issuesOpen})
}
情景3:你能把整个app.get()路由都分解出来吗? 甚至可以分解整个
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
)

手动添加一些承诺(可以使用
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);
};

最后一个似乎是最简单的。不,只需调用那些
\u complete…Route
函数,并确保将
db
作为参数传递给它们。
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);
};