将嵌套回调转换为 Promise
Converting a nested callback to a Promise
我想尝试将此函数转换为基于 Promise
的函数,以便解决所有这些嵌套回调和来自 ESLint consistent-return 的 return
警告。
之前,我在这里寻求一些帮助来克服我的 return 语句的 ESLint 错误,因为它们不一致或遵循 JS 的最佳实践。
我的第一个想法是简单地在 remove
函数中执行 return new Promise((resolve, reject) => {...})
,但这只会 promisify 整个事情,而不仅仅是函数内部的内容,所以我觉得这不是最好的方法这样做。
感谢任何帮助!
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` });
});
});
}
不确定是否明白你的意思,但你可能想尝试以下方法
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);
});
}
您可能已经在上面注意到,一些行为已被提取到 return Promise 的函数中。
本可以进一步优化,但我只是想向您展示 Promises 的可能性。
有帮助吗?
这是您可以使用的另一种方法。我从 "promisifying" 开始,每个 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);
}
});
}
我想尝试将此函数转换为基于 Promise
的函数,以便解决所有这些嵌套回调和来自 ESLint consistent-return 的 return
警告。
之前,我在这里寻求一些帮助来克服我的 return 语句的 ESLint 错误,因为它们不一致或遵循 JS 的最佳实践。
我的第一个想法是简单地在 remove
函数中执行 return new Promise((resolve, reject) => {...})
,但这只会 promisify 整个事情,而不仅仅是函数内部的内容,所以我觉得这不是最好的方法这样做。
感谢任何帮助!
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` });
});
});
}
不确定是否明白你的意思,但你可能想尝试以下方法
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);
});
}
您可能已经在上面注意到,一些行为已被提取到 return Promise 的函数中。
本可以进一步优化,但我只是想向您展示 Promises 的可能性。
有帮助吗?
这是您可以使用的另一种方法。我从 "promisifying" 开始,每个 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);
}
});
}