将嵌套回调转换为承诺

Converting a nested callback to a Promise

本文关键字:承诺 转换 回调 嵌套      更新时间:2023-09-26

我想试着把这个函数转换成一个基于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` });
    });
  });
}

还有另一种方法。我首先"承诺"每个findOneremoveUser作为单独的功能。然后,你的路线几乎自动简化了。

你还可以做一些改进,但也许你可以从中学到一些东西。

(感谢@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的函数中。

可能已经优化了更多,但我只是想告诉你什么是可能的承诺。

有帮助吗?