解决后如何停止承诺链? [英] How to stop promise chain after resolve?

查看:52
本文介绍了解决后如何停止承诺链?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在通过某些条件解决后停止承诺链.下面的代码可能有助于理解我在说什么.

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) => { ... })
    });
}

注意 pool.get() 是 promise 封装的 API,用于从我制作的 MySQL 模块获取连接池.

Note that pool.get() is promise wrapped API for getting connection pool from MySQL module that I made.

我想做的是更新用户数据.为了节省服务器资源,我避免在没有数据更新时更新(Object.keys(data).length === 0).

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!

我阅读了这篇文章,但它没有用.为什么当我调用return resolve();"时承诺链没有停止?以及如何正确停止它?我真的很喜欢使用 Promises,但有时,这种事情让我发疯.帮助我解决这个问题将不胜感激.谢谢!

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!

附言反正我用的是 node v6.2.2.

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

推荐答案

为什么我调用return resolve();"时promise链没有停止?

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

您已经从当前的 then 回调中返回并实现了外部承诺.但这并不能停止"任何事情,那么 then 链仍然会继续通过回调的返回值进行解析.

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.

以及如何正确停止它?

您需要then 调用放入if 让条件适用于它:

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) => { ... })

在任何情况下,您都应该避免 Promise 构造函数反模式!您应该只promisifyquery 方法:

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

然后使用它:

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(); // ???
            });
        }
    });
}

请注意,如果您事先知道不会进行查询,那么从池中获取连接可能没有意义,因此您可能应该将 if 放在顶层:

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(); // ???
            });
        });
    }
}

这篇关于解决后如何停止承诺链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆