Javascript Promise Chaining - это принято? - PullRequest
0 голосов
/ 14 марта 2019

Я обеспокоен своим кодом, хотя он работает.

Как говорится в названии, это принято?Потому что в моей базе данных мне нужно выполнить Обещание 1, прежде чем перейти к Обещанию 2, потому что мне нужно получить доступ к переменным и результатам Обещания 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 ]

2 голосов
/ 14 марта 2019

Проблема может быть внутри .then(data => { части.Вы создаете новое Обещание там, но не возвращаете его в другую цепочку.Может случиться, что это обещание не будет выполнено, потому что обещание оболочки не делает попыток сделать это, поскольку оно не возвращается.

Вы можете изменить свой код следующим образом:

.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.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())) в этом случае.

РЕДАКТИРОВАТЬ: еще несколько объяснений цепочки обещаний.

0 голосов
/ 14 марта 2019

Если обещания не зависят друг от друга? Это означает, что вам не нужна информация из первого обещания, прежде чем вы сможете получить второе, тогда да, вы можете связать их вместе.

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)
    })
0 голосов
/ 14 марта 2019

Чтобы сделать это цепочкой, ваш код должен выглядеть примерно так:

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

И я рекомендую прочитать о цепочке обещаний, например, это: https://javascript.info/promise-chaining

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...