简体   繁体   English

解决后如何停止承诺链?

[英]How to stop promise chain after resolve?

I want to stop promise chain after it resolved via some conditions.我想在通过某些条件解决后停止承诺链。 Below code is might useful to understand what am I saying.下面的代码可能有助于理解我在说什么。

function update(id, data) {
    return new Promise((resolve, reject) => {
        let conn;

        pool.get()
        .then((db) => {
            conn = db;

            if(Object.keys(data).length === 0) {
                return resolve({ updated: 0 });
            }
            else {
                return generateHash(data.password);
            }
        })
        .then((hash) => {
            conn.query("UPDATE ... ", (err, queryResult) => {
                if(err) {
                    throw err;
                }

                resolve({ updated: queryResult.affectedRows });
            });
        })
        .catch((err) => { ... })
    });
}

Note that pool.get() is promise wrapped API for getting connection pool from MySQL module that I made.请注意,pool.get() 是用于从我制作的 MySQL 模块获取连接池的承诺包装 API。

What I'm trying to do is updating user data.我想做的是更新用户数据。 And for save server resources, I avoided to update if no data to update(Object.keys(data).length === 0).为了节省服务器资源,我避免在没有数据更新时更新(Object.keys(data).length === 0)。

When I tried this code, second then(updating db) is always happening even if no data to update!当我尝试此代码时,即使没有要更新的数据,第二次(更新数据库)也会始终发生!

I read this post , but it didn't worked.我读了这篇文章,但没有奏效。 Why the promise chain wasn't stopped when I called "return resolve();"?为什么当我调用“return resolve();”时承诺链没有停止? And how to I stop it properly?以及如何正确停止它? I really like using Promises, but sometimes, this kind of things make me crazy.我真的很喜欢使用 Promises,但有时,这种事情让我发疯。 It will be very appreciate to help me this problem.帮助我解决这个问题将不胜感激。 Thanks!谢谢!

PS I'm using node v6.2.2 anyway. PS无论如何我都在使用节点v6.2.2。

Why the promise chain wasn't stopped when I called "return resolve();"?为什么当我调用“return resolve();”时承诺链没有停止?

You've returned from the current then callback and fulfilled the outer promise.您已经从当前then回调返回并实现了外部承诺。 But that doesn't "stop" anything, then then chain still will continue by resolving with the return value of the callback.但是,这并不“一站式”什么,然后then链条还是会继续通过与回调的返回值解决。

And how to I stop it properly?以及如何正确停止它?

You need to put the then call inside the if to have the condition apply to it:您需要then调用放在if以使条件适用于它:

pool.get()
.then((db) => {
    …
    if (Object.keys(data).length === 0) {
        …({ updated: 0 });
    } else {
        return generateHash(data.password)
        .then((hash) => {
            conn.query("UPDATE ... ", (err, queryResult) => {
                …
            });
        })
    }
})
.catch((err) => { ... })

And in any case, you should avoid the Promise constructor antipattern !无论如何,您应该避免使用Promise构造函数反模式 You should only promisify the query method:您应该只承诺query方法:

function query(conn, cmd) {
    return new Promise((resolve, reject) => {
        conn.query(cmd, (err, queryResult) => {
            if (err) reject(err); // Don't throw!
            else resolve(queryResult);
        });
    });
}

and then use that:然后使用它:

function update(id, data) {
    return pool.get()
    .then(conn => {
        if (Object.keys(data).length === 0) {
            conn.close(); // ???
            return { updated: 0 };
        } else {
            return generateHash(data.password)
            .then(hash => {
                return query(conn, "UPDATE ... ")
            }).then(queryResult => {
                conn.close(); // ???
                return { updated: queryResult.affectedRows };
            }, err => {
                …
                conn.close(); // ???
            });
        }
    });
}

Notice that it might not make sense to get a connection from the pool if you can know beforehand that no query will be made, so probably you should put the if on the top level:请注意,如果您事先知道不会进行查询,那么从池中获取连接可能没有意义,因此您可能应该将if放在顶层:

function update(id, data) {
   if (Object.keys(data).length === 0) {
       return Promise.resolve({ updated: 0 });
    } else {
       return pool.get()
       .then(conn => {
            return generateHash(data.password)
            .then(hash => {
                return query(conn, "UPDATE ... ")
            }).then(queryResult => {
                conn.close(); // ???
                return { updated: queryResult.affectedRows };
            }, err => {
                …
                conn.close(); // ???
            });
        });
    }
}

This would be a good situation to use an if statement:这将是使用if语句的好情况:

function update(id, data) {
    if (Object.keys(data).length === 0) {
        return Promise.resolve({ updated: 0 }); 
    }

    let conn;

    return pool.get()
        .then((db) => {
            conn = db;

            return generateHash(data.password);
        })
        .then((hash) => {
            return new Promise(function (resolve, reject) {
                conn.query("UPDATE ... ", (err, queryResult) => {
                    if(err) {
                        reject(err);
                    }

                    resolve({ updated: queryResult.affectedRows });
                });
            });
        })
        .catch((err) => { ... })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM