我希望在通过某些条件解决后停止承诺链。下面的代码可能有助于理解我在说什么。
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模块获取连接池。
我要做的是更新用户数据。为了节省服务器资源,如果没有要更新的数据,我就避免更新(Object.keys(data).length === 0)。
当我尝试使用此代码时,即使没有要更新的数据,也会发生第二次(更新数据库)!
我看了this post,但没有奏效。当我调用“return resolve();”时为什么没有停止承诺链?我该如何正确地阻止它?我真的很喜欢使用Promises,但有时候,这种事情会让我发疯。非常感谢帮助我解决这个问题。谢谢!
P.S。无论如何,我正在使用节点v6.2.2。
答案 0 :(得分:5)
当我打电话给#34;返回resolve();"?
时,为什么承诺链没有停止?
您已从当前then
回调中退回并履行了外部承诺。但那并没有停止"任何事情,然后then
链仍然会继续解析回调的返回值。
如何正确阻止它?
您需要put the then
call inside the 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) => { ... })
无论如何,你应该避免使用Promise
constructor antipattern!您应该只promisify 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);
});
});
}
然后使用:
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
置于顶层:
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(); // ???
});
});
}
}
答案 1 :(得分:0)
使用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) => { ... })
}