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

时间:2017-09-29 10:12:55

标签: javascript express ecmascript-6

如何根据先前的变量

分解/导出回调函数

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

前提条件

使用大型回调函数考虑以下代码:

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:打破整个回调(这有效)

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
)

情况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
)

_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
)

1 个答案:

答案 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);
};