最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to stop promise chain after resolve? - Stack Overflow

programmeradmin6浏览0评论

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.

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

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();"? And how to I stop it properly? I really like using Promises, but sometimes, this kind of things make me crazy. It will be very appreciate to help me this problem. Thanks!

P.S. I'm using node v6.2.2 anyway.

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.

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

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();"? And how to I stop it properly? I really like using Promises, but sometimes, this kind of things make me crazy. It will be very appreciate to help me this problem. Thanks!

P.S. I'm using node v6.2.2 anyway.

Share Improve this question edited May 23, 2017 at 10:34 CommunityBot 11 silver badge asked Oct 10, 2016 at 9:49 modernatormodernator 4,42714 gold badges48 silver badges77 bronze badges 8
  • firstly, you're using the Promise constructor antipattern ... secondly, resolving in one part of the chain guarantees to fall through to the next .then - that's how promise chains work! – Jaromanda X Commented Oct 10, 2016 at 9:59
  • You can take help here stackoverflow./questions/20714460/… – abdulbari Commented Oct 10, 2016 at 9:59
  • Why would you wait until after you pool.get before checking if the ining data has no keys? – Jaromanda X Commented Oct 10, 2016 at 10:05
  • @torazaburo - that would be the value of hash in the next .then callback – Jaromanda X Commented Oct 10, 2016 at 10:09
  • though ... hash doesn't seem to be used at all – Jaromanda X Commented Oct 10, 2016 at 10:10
 |  Show 3 more ments

2 Answers 2

Reset to default 5

Why the promise chain wasn't stopped when I called "return resolve();"?

You've returned from the current then callback and fulfilled the outer promise. But that doesn't "stop" anything, then then chain still will continue by resolving with the return value of the callback.

And how to I stop it properly?

You need to put the then call inside the if to have the condition apply to it:

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! You should only promisify the query method:

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:

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:

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) => { ... })
}
发布评论

评论列表(0)

  1. 暂无评论