Javascript Promise Chaining-是否接受?

时间:2019-03-14 08:31:22

标签: javascript node.js postgresql express

我正在担心我的代码,尽管它可以正常工作。

正如标题所述,它被接受了吗?因为在我的数据库中,我需要先完成Promise 1,然后再进行Promise 2,因为我需要访问Promise 1的变量和结果。

简而言之,我的数据库中发生的事情是这样的:

  1. 然后插入:user_tbl
  2. 插入:login_tbl

请注意,在login_tbl中,有一列是user_tbl的外键。因此,我必须先完成在user_tbl中的插入,否则会出现错误。

顺便说一句,我正在使用postgresql,knex.js和bcrypt 这是我的代码:

//This is the function that handles the signup
const handleSignup = (req, res, db, bcrypt) => {

const { employeeId, username, password, firstName, lastName, positionSelect } = req.body;

const hash = bcrypt.hashSync(password);

if (!employeeId || !username || !password || !firstName || !lastName || !positionSelect) {
    res.json({
        haveEmpty: true
    })
}
else{
    db.transaction((trx) => {
        db.select('*').from('user').where('employee_id', '=', employeeId)
        .then(data => {
            if(!data[0]){
                db('user')
                .returning('*')
                .insert({
                    employee_id: employeeId,
                    username: username,
                    first_name: firstName,
                    last_name: lastName,
                    status: "Active",
                    position_id: positionSelect
                })
                .then(user =>{
                    db('login')
                    .returning('*')
                    .insert({
                        employee_id: employeeId,
                        username: username,
                        hash: hash
                    })
                    .then(login => {
                        if(login[0]){
                            res.json({
                                isSuccess: true
                            })
                        }else{
                            res.json({
                                isSuccess: false
                            })
                        }
                    })
                    .then(trx.commit)
                    .catch(trx.rollback);
                })
                .then(trx.commit)
                .catch(trx.rollback);
            }
            else {
                res.json('User already Exist!')
            }
        })
        .then(trx.commit)
        .catch(trx.rollback);
    })
    .catch(err => console.error(err));
}
}

3 个答案:

答案 0 :(得分:2)

问题可能在.then(data => {部分内部。您在此处创建一个新的Promise,但没有将其返回到另一个链接。我可能会碰巧,这个诺言将无法解决,因为包装诺言没有做任何尝试,因为它没有返回。

您可以按以下方式更改代码:

.then(data => {
    if(!data[0]){
        return db('user')

.then(user =>{
    return db('login')

如果创建了一个承诺但没有返回,则下一个then将什么也没有:

Promise.resolve('abc')
    .then(res => { Promise.resolve(res.toUpperCase()); })
    .then(res => console.log(res) /*prints undefined*/);

{ Promise.resolve(res.toUpperCase()); }块创建了一个Promise,但是没有返回任何内容,这意味着Promise不会进一步连锁,也无法解决。

一切都很好,当诺言返回时,诺言就进入了链条:

Promise.resolve('abc')
    .then(res => { return Promise.resolve(res.toUpperCase()); })
    .then(res => console.log(res) /*prints ABC*/);

在这种情况下,.then(res => { return Promise.resolve(res.toUpperCase()); })可以缩短为.then(res => Promise.resolve(res.toUpperCase()))

编辑:更多关于诺言链的解释。

答案 1 :(得分:0)

要使其成为一条链,您的代码应更像这样:

db.transaction((trx) => {
    return db.select('*').from('user').where('employee_id', '=', employeeId).then(data =>{
        if(data[0]) {
            res.json('User already Exist!')
            //if it's possible use `return` instead `else`
            return null;
        }
        return db('user')
            .returning('*')
            .insert({
                employee_id: employeeId,
                username: username,
                first_name: firstName,
                last_name: lastName,
                status: "Active",
                position_id: positionSelect
        }).then(user=>{
            return db('login')
                .returning('*')
                .insert({
                    employee_id: employeeId,
                    username: username,
                    hash: hash
                })
        }).then(login =>{
            if(login[0]){
                res.json({
                    isSuccess: true
                })
            }else{
                res.json({
                    isSuccess: false
                })
            }
            return true
        }).then(trx.commit)
        .catch(trx.rollback)
    })
}).catch(err=> {
    console.error(err)
    res.status(500).json({error: true})
})

我建议阅读有关Promises链的信息,例如:https://javascript.info/promise-chaining

答案 2 :(得分:0)

如果诺言不相互依赖?这意味着在获取第二个承诺之前,您不需要第一个承诺中的信息,然后可以将它们链接在一起。

const Promise1 = fetch('https://API_URL_1');
const Promise2 = fetch('https:/API_URL_2');

Promise
    .all([Promise1,Promise2])
    .then(responses => {
        return Promise.all(responses.map(res => res.json()))
    })
    .then(responses => {
      console.log(responses)
    })
    .catch(err => {
      console.error(error)
    })