【问题标题】:What is the difference between throwing inside .then block or within async await block?在 .then 块内或在异步等待块内抛出有什么区别?
【发布时间】:2021-03-23 07:08:34
【问题描述】:

我收到此错误:

(node:9868) UnhandledPromiseRejectionWarning: #<Object>
(node:9868) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9868) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code

我正在使用如下所示的快速错误处理程序包装 create 方法:

export const errorHandler = (callback: any) => {
  return (req: Request, res: Response, next: NextFunction) => {
    callback(req, res, next).catch(next);
  };
};

当我尝试这样做时:

async create(entity: T){
 this._model
        .findOne({ name: (entity as any).name })
        .then((res) => {

          if (res) {
            throw Exceptions.ENTITY_EXISTS; // doesnt work 
          }
        })
}

但是,当我将其更改为异步等待时,它可以正常工作

async create(entity: T) {
     const res = await this._model.findOne({ name: (entity as any).name });
     if (res) throw Exceptions.ENTITY_EXISTS;
}

当我尝试做而不是 throw Promise.reject(Exceptions.ENTITY_EXISTS) 时,它也抛出了同样的错误。

谁能解释一下这三者之间的区别,以及为什么只有异步等待起作用?

【问题讨论】:

    标签: javascript node.js ecmascript-6 es6-promise


    【解决方案1】:

    区别确实在于throw 发生的位置。在工作版本中,它将create()返回的promise设置为rejected。

    在非工作版本中,它使.then() 返回的承诺结算为被拒绝。然而,这个promise 不是create() 返回的那个promise,所以即使你正确处理了create() 上的拒绝……它也不能处理then() 上发生的拒绝。它们没有连接,因此您无需处理该拒绝。

    要修复第一个版本,请确保返回.then()返回的承诺:

    create(entity: T){
        return this._model
    //  ^^^^^^
            .findOne({ name: (entity as any).name })
            .then((res) => {
                if (res) {
                    throw Exceptions.ENTITY_EXISTS; // doesnt work 
                }
            });
    }
    

    注意:虽然你可以在函数之前保留async,但如果你不使用await 并返回一个promise,它确实不是那么有用。

    NB2:由于缺少returncreate 函数实际上返回了一个立即解决的承诺......所以它从不等待数据库查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      • 2015-08-20
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多