将嵌套回调转换为承诺
Converting a nested callback to a Promise
我想试着把这个函数转换成一个基于Promise
的函数,以解决所有这些嵌套的回调和来自ESLint的return
警告。
之前,我请求了一些帮助来克服我的返回语句在这里的ESLint错误,因为它们不一致或遵循JS的最佳实践。
我的第一个想法是简单地在remove
函数中执行return new Promise((resolve, reject) => {...})
,但这只会承诺整个事情,而不仅仅是函数内部的内容,所以我觉得这不是最好的方法。
感谢任何帮助!
function remove(req, res) {
User.findOne({ username: req.params.username }, (findErr, existingUser) => {
if (findErr) return res.status(500).send(errorHandler.getErrorMessage(findErr));
if (!existingUser) return res.status(404).send({ message: 'User not found' });
existingUser.remove((removeErr) => {
if (removeErr) return res.status(500).send(errorHandler.getErrorMessage(removeErr));
return res.json({ message: `${existingUser.username} successfully deleted` });
});
});
}
还有另一种方法。我首先"承诺"每个findOne
和removeUser
作为单独的功能。然后,你的路线几乎自动简化了。
你还可以做一些改进,但也许你可以从中学到一些东西。
(感谢@Bergi的有用建议)
const error = (type, message) => Object.assign(new Error(message), {type});
const wrapError = type => err => { throw error(type, errorHandler.getErrorMessage(err));};
const findUser = opts => {
return new Promise((resolve, reject) => {
User.findOne(opts, (err, user) => {
if (err) reject(err);
else resolve(user);
});
}).then(user => {
if (!user) throw error('USER_NOT_FOUND', 'User not found')
else return user;
}, wrapError('USER_FIND_ERROR'));
};
const removeUser = user => {
return new Promise((resolve, reject) => {
user.remove(err => {
if (err) reject(err);
else resolve();
});
}).catch(wrapError('USER_REMOVE_ERROR'));
};
function remove(req, res) {
findUser({ username: req.params.username })
.then(removeUser)
.then(() => res.json({message: `${req.params.username} successfully removed`}))
.catch(error) => {
switch (error.type) {
case 'USER_NOT_FOUND':
return res.status(404).send(error.message);
// case 'USER_FIND_ERROR':
// case 'USER_REMOVE_ERROR':
default:
console.error(error.type, error.message, error.stack);
return res.status(500).send(error.message);
}
});
}
不确定是否明白你的意思,但你可能想尝试以下
const findUser = (username) => {
return new Promise((resolve, reject) => {
User.findOne({ username }, (error, user) => {
if (error) {
reject({ type: 'error', details: errorHandler.getErrorMessage(error) });
return;
}
if (!user) {
reject({ type: 'not-found', details: { message: 'User not found' } });
return;
}
resolve(user);
});
});
};
const removeUser = (username) => {
return new Promise((resolve, reject) => {
findUser(username)
.then(user => {
user.remove((error) => {
if (error) {
reject({ type: 'error', details: errorHandler.getErrorMessage(error) });
return;
}
// Simply resolve on success
resolve();
});
})
.catch(error => reject(error));
});
};
function remove(req, res) {
removeUser(req.params.username)
.then(() => res.json({ message: `${req.params.username} successfully deleted` }))
.catch(error => {
if (error.type === 'not-found') {
return res.status(404).send(error.details);
}
return res.status(500).send(error.details);
});
}
正如你在上面可能已经注意到的,一些行为已经被提取到返回promise的函数中。
可能已经优化了更多,但我只是想告诉你什么是可能的承诺。
有帮助吗?
相关文章:
- 如何将嵌套设置超时转换为承诺
- 如何重构“;回调金字塔”;转换为基于承诺的版本
- 转换嵌套'对于'循环成一个承诺,为了一个承诺?嵌套承诺
- 使用 jQuery 承诺等待转换
- 将 for 循环转换为 Q 承诺
- 将元素数组转换为承诺并将其返回
- 可观察 - 将 2 个承诺转换为可观察
- 实现时,将承诺数组转换为值数组
- 转换被拒绝的承诺中的值
- Node.js:使用Bluebird将模块函数从回调转换为承诺
- 将嵌套回调转换为承诺
- Javascript将我的身份验证函数转换为承诺
- 扩展ES6承诺,将回调转换为Deferred模式
- Angular UI-Router——在resolve中返回被拒绝的承诺并不能停止状态转换
- 将承诺的变量转换为正常的单角变量
- 使用when/node将Amazon S3函数转换为承诺时出错
- 将带有回调的方法转换为返回带有清理的承诺的方法
- 如何将被拒绝的承诺转换为异常,并从Express路由处理程序抛出该异常?
- Javascript承诺转换
- 将承诺转换为蓝鸟