承诺链未按顺序执行

pvcm50d1  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(269)

我遇到了一个奇怪的问题,我在以下代码中调用“createproductline”:

module.exports.postProductLine = (req, res) => {
    DAL.createProductLine(req.body.category, req.body.type, req.body.name, req.body.description, req.body.tags)
    .then(() => {
        res.sendStatus(200)
        console.log("SUCCESS")
    })
    .catch(err => {
        res.status(500).send(err.message)
        console.error(err)
    })
}

下面是“createproductline”函数:

module.exports.createProductLine = async (category, type, name, description, tags) => {
    const [pool, dbErr] = await tryCatch(await database.pool)
    if(dbErr) return Promise.reject()
    const [connection, connectErr] = await tryCatch(pool.getConnection())
    if(connectErr) return Promise.reject()
    connection.beginTransaction()
    .then(() => {
        const query = `INSERT INTO product_lines (category,type,name,description,last_update,creation_date) VALUES (?,?,?,?,NOW(),NOW())`
        return connection.query(query, [category, type, name, description])
    })
    .then(({insertId: productLineId} = {}) => Promise.all([
        Promise.resolve(productLineId),
        ...tags.map(productLineTag => new Promise(async (resolve, reject) => {
            let query = "SELECT id FROM tags WHERE name=?"
            const [existingTag, err1] = await tryCatch(connection.query(query, [productLineTag]))
            if(err1) return reject(`could not get tag (${productLineTag}) id`)
            if(existingTag.length === 0) {
                query = "INSERT INTO tags (name) VALUES (?)"
                const [{insertId}, err2] = await tryCatch(connection.query(query, [productLineTag]))
                if(err2) return reject(`could not insert tag (${productLineTag})`)
                return resolve(insertId)
            }
            return resolve(existingTag[0].id)
        }))
    ]))
    // CHANGE OF ORDER HAPPENS HERE
    .then(ids => Promise.all(
        ids.reduce((acc, cur, i, arr) => {
            if(i === 0) return acc
            acc[i - 1] = connection.query(
                `INSERT INTO product_lines_tags (product_line_id, tag_id) VALUES (${arr[0]}, ${cur})`
            )
            return acc
        }, new Array(ids.length - 1))
    ))
    .then(async () => {
        console.log("THEN")
        await connection.commit()
        return connection.release()
    })
    .catch(async err => {
        console.log("CATCH", err)
        await connection.rollback()
        await connection.release()
        return err
    })
}

由于某种原因,所有的.then的执行顺序并不像预期的那个样,在完成第二个之后(在“createproductline”内部),它在第一个代码块(postproductline函数)中执行.then,然后返回来执行其余的。
我不明白它为什么会这样,有人知道如何解决这个问题吗?

btqmn9zl

btqmn9zl1#

module.exports.createProductLine = async (category, type, name, description, tags) => {
    const pool = await database.pool
    const connection = await pool.getConnection()
    await connection.beginTransaction()
    try {
        const {insertId: productLineId} = await connection.query(
            "INSERT INTO product_lines (category,type,name,description) VALUES (?,?,?,?)", 
            [category, type, name, description]
        )
        const tagIds = await Promise.all(tags.map(async tag => {
            const existingTag = await connection.query(
                "SELECT id FROM tags WHERE name=?", [tag]
            )
            if(existingTag.length === 0) { 
                const {insertId} = await connection.query(
                    "INSERT INTO tags (name) VALUES (?)", [tag]
                )
                return insertId
            }
            return existingTag[0].id
        }))
        await Promise.all(tagIds.map(tagId => connection.query(
            `INSERT INTO product_lines_tags (product_line_id, tag_id) VALUES (${productLineId}, ${tagId})`
        )))
        await connection.commit()
        await connection.release()
        return true
    }
    catch(err) {
        await connection.rollback()
        await connection.release()
        return Promise.reject(err)
    }
}

相关问题