正确使用带有回调函数的 async/await

问题描述

我正在尝试在 mongo 之上构建一个服务层。我有一个 User 对象,其中包含一组引用的 Achievements

通过 JWT 或其他方式对用户进行身份验证后,我进入服务层并查询关系如下。

findForUser(userId: string | Types.ObjectId): Promise<Achievement[]> {
  return new Promise((resolve) => {
    UserSchema.findOne({ _id: userId },async (err: any,user: User) => {
        const AchievementMap: Achievement[] = [];

        if (err) throw new Error(err);
        user.achievements?.forEach((a) => {
          // @ts-ignore
          AchievementMap.push(a);
        });
        resolve(AchievementMap);
      });
  });
}

我的问题是,返回传递给 UserSchema.findOne 的回调方法的结果的异步/等待方法是什么?

解决方法

返回回调结果的 async/await 方法是什么

asyncawait 关键字是管理承诺的工具。它们不是管理回调的工具。

您在问题中的代码的全部要点是围绕处理回调的函数包装基于承诺的 API。

现在您有一个承诺,您可以await findForUser 的返回值。

您不能使用 asyncawait 代替来创建承诺。

,

findOne 返回一个可等待的对象 - 所以你不需要向它传递回调。不要尝试将回调与 async/await 混合使用。作为构造承诺的结果,从回调返回值的唯一方法是使用 resolve(仅在承诺执行程序中可用)。

相反,全部async - 功能相似但更简洁。

async findForUser(userId: string | Types.ObjectId): Promise<Achievement[]> {
    const user = await UserSchema.findOne({ _id: userId });

    const AchievementMap: Achievement[] = [];
    user.achievements?.forEach(a => {
        AchievementMap.push(a);
    });
    return AchievementMap;
}