【问题标题】:Await isn't waiting for promise to resolveAwait 不是在等待 promise 解决
【发布时间】:2021-05-19 00:08:09
【问题描述】:

大家晚上好!

我已经在这个问题上停留了一段时间,我似乎无法通过纯粹的谷歌搜索来解决它,所以我正在与大家联系。

背景: 我正在编写一个小应用程序来处理我们公司所有实习生的所有日历和基本项目信息,因为我的老板经常问我他们在做什么,我想给他一些他可以看的东西,所以我决定用代码解决它,同时也在这个过程中学习一个新的框架(Express)。

现在我已经设置好了我的路线,我已经设置了我的控制器,并且我已经设置了我的数据库光标。当我调用我定义的路由时,它运行 getAllUsers() 控制器函数,并在该控制器函数中使用 DB 游标上的 getAllUsers() 函数调用数据库,我希望代码等待DB 游标在继续之前返回其结果,但它不是,我不知道为什么。 DB 游标代码确实有效,因为它可以很好地获取数据并将其记录下来。

任何帮助将不胜感激,我已将这三位有问题的代码放在下面,如果您需要我展示更多内容,请告诉我。

p.s 忽略“here1”、“here2”等调用,这就是我一直在计算任何时间点发生的事情的方式。

routes.ts

import express from 'express';
import controllers from './controller.js';

export default (app: express.Application) => {
    // Users
    app.route('/users').get(controllers.getAllUsers)
    app.route('/users').post(controllers.postNewUser)
    app.route('/users').delete(controllers.deleteUser)
    app.route('/user/:emailAddress').get(controllers.getUser)
    app.route('/user/:emailAddress').put(controllers.updateUser)
}

controllers.ts

import express from 'express';
import dbcursor from '../services/dbcursor.js';

// Interfaces
import { Project, User } from '../services/interfaces.js'

const controllers = {

    // Users
    getAllUsers: async (req: express.Request, res: express.Response) => {
        try {
            const dbRes = await dbcursor.getAllUsers();
            console.log('here 3', dbRes)
            res.status(200).json({
                message: 'Users fetched succesfully!',
                dbRes: dbRes
            });
        } catch (err) {
            res.status(400).json({
                message: 'Failed to get users.',
                dbRes: err
            });
            
        }
    },
}

dbcursor.ts

import dotenv from 'dotenv';
import mongodb from 'mongodb' 

dotenv.config();

// Interfaces
import { User, Project } from './interfaces'

// DB Client Creation
const { MongoClient } = mongodb;
const uri = process.env.DB_URI || ''
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

const dbcursor = {
    
    // Users
    getAllUsers: async () => {
        let dbRes;
        try {
            await client.connect(async err => {
                if (err) throw err;
                console.log("here 1", dbRes)
                const collection = client.db("InternManager").collection("Users");
                dbRes = await collection.find().toArray()
                console.log("here 2", dbRes)
                return dbRes;
            });
        } catch(err: any) {
            return err;
        }
    },
}

【问题讨论】:

  • client.connect 似乎没有产生承诺,因为它需要回调。所以,等待它不会做任何事情。此外,return dbRes 返回 从回调 它不适用于 getAllUsers
  • 每天,这里都会有几十个问题,人们在某个操作前抛出一个等待,并期望它会发生奇迹。如果您正在等待与异步操作完成相关的承诺,则 await 只会做一些有用的事情。而且,几乎总是如果您将回调传递给某个函数,那么它将不会返回承诺。我建议您阅读this answer 中的 10 条承诺/等待指南,因为其中有几条适用于您。

标签: javascript node.js typescript express async-await


【解决方案1】:

混合回调和承诺通常不是一个好主意。尽量不要将回调传递给client.connect 方法,您应该能够按预期向await 承诺

    getAllUsers: async () => {
        let dbRes;
        try {
            await client.connect();
            console.log("here 1", dbRes)
            const collection = client.db("InternManager").collection("Users");
            dbRes = await collection.find().toArray()
            console.log("here 2", dbRes)
            return dbRes;
        } catch(err: any) {
            throw err; // If you're just catching and throwing the error, then it would be okay to just ignore it 
        }
    },

【讨论】:

  • 谢谢@Shadab 解决了这个问题,当你指出它时,它看起来很简单。是否有理由认为混合它们不是一个好主意,还是只是为了防止像我这样的混乱发生?
猜你喜欢
  • 1970-01-01
  • 2020-06-23
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多