【问题标题】:Promise not resolving but resolve() is being reached inside of the promise callback承诺未解决,但在承诺回调中达到了 resolve()
【发布时间】:2019-11-29 08:08:49
【问题描述】:

我正在尝试编写一个类似于 Laravel 中的查询构建器但针对 TypeScript 的查询构建器,但我遇到了一个解决承诺的问题。

在下面的这段代码中,我减少了我的构建器和控制器类。使用这个库https://github.com/mysqljs/mysql,我使用代码connection.query(...) 运行一个查询,我传入一个回调函数来处理响应并相应地解决/拒绝。我不明白的是它到达console.log 并将其输出到我的控制台中,但控制器中的.then() 没有被调用。

import * as mysql from 'mysql';

interface InternalQueryReturnType<T> {
  results: T;
  fields?: mysql.FieldInfo[];
}

// Cut down version of my builder.
export class MySQLBuilder implements IQueryBuilder {
  protected query<T>(query: string): Promise<InternalQueryReturnType<T>> {
    return new Promise((resolve, reject) => {
      const connection = mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: '',
        database: 'dbname',
        port: 999,
      });

      connection.connect({}, (error) => {
        reject(error);
      });

      connection.query(query, (error, results, fields) => {
        if (error) {
          reject(error);
          return;
        }

        // It is reaching this point.
        console.log({ results }); // <- This is returning the correct results.
        resolve({ results, fields });
      });

      connection.end();
    });
  }
}

// My controller.
export class PostController {
  public static index(request: IRequest): Promise<IResponse> {
    return new Promise((resolve, reject) => {
      return new Promise((resolve) => {
        // Testing the raw query which the builder created.
        new MySQLBuilder().query<any>('SELECT * FROM `users` WHERE `id` = 1 LIMIT 1 OFFSET 0')
          .then(({ results }) => {
            // Nothing was passed into this.
            console.log({ results });
            resolve(new JsonResponse(results || {}));
          })
          .catch((error) => {
            resolve(new JsonResponse(error).status(400));
          });

        // Builder code.
        // new MySQLBuilder().table('users')
        //   .where('id', '=', 1)
        //   .first()
        //   .then((value: object | null) => {
        //     console.log(value);
        //     resolve(new JsonResponse(value || {}));
        //   })
        //   .catch((error) => {
        //     console.error({ error });
        //     resolve(new JsonResponse(error).status(400));
        //   });
      });
    });
  }
}

有人遇到过这个promise问题吗?

如果您需要整个代码库,我可以稍后将其全部放好,但这应该足够了。

这个问题的解决方案其实是这样的:

connection.connect({}, (error) => {
  if (error) {
    reject(error);
  }
});

【问题讨论】:

  • 所以.then 没有被调用。是否调用了 .catch(返回 400 错误)?
  • 没关系,我是特别的雪花。问题在于connection.connect() not 检查错误是否为空,哈哈。
  • 您的许多 Promise 构造函数很奇怪,应该重构 stackoverflow.com/questions/23803743/… 但如果代码与您逐字显示的一样,它们不应该在这里引起问题

标签: javascript mysql typescript es6-promise


【解决方案1】:

这个问题的解决方案其实是这样的:

connection.connect({}, (error) => {
  if (error) {
    reject(error);
  }
});

我没有检查错误是否为 NULL。

【讨论】:

  • 有趣。我认为这是.connect 方法的错误。如果有错误,它应该包含某种信息。大多数人,像你一样,会认为错误的错误意味着没有错误。
  • 在他们的文档中,它确实显示了所有捕获错误然后抛出错误的示例。我认为这是在提供多个参数的函数之间保持一致。例如。 (error, results, fields)。虽然我正在考虑寻找一个不同的 MySQL 库,因为这个库不支持准备好的语句,我不会像这样推送任何东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-16
  • 2016-07-20
  • 2016-06-15
  • 1970-01-01
  • 2015-06-24
  • 2020-10-22
  • 2014-12-15
相关资源
最近更新 更多