【问题标题】:Node/Express and MongoDB: Async/Await with Model.create()Node/Express 和 MongoDB:Async/Await 与 Model.create()
【发布时间】:2018-06-07 17:03:39
【问题描述】:

我目前正在开发一个 MEAN 项目,后端使用 TypeScript。一切正常。但是,我想知道以下代码块:

TodoSchema.static('createTodo', async (newTodo: ITodo) => {
    return await Todo.create(newTodo)
        .then((result: ITodo) => result)
        .catch((error: MongoError) => error);
});

上面的代码块工作正常,但我相信它对于async/await 看起来有点多余。下面是调用上述函数的代码块:

const result = await Todo.createTodo(newTodo);
    if (result instanceof MongoError) TodoController.resolveErrorResponse(res, result.message, 500, result);
    if ((typeof(result)) === 'undefined' && !result) TodoController.resolveErrorResponse(res, 'Error saving Todo', res.statusCode);

这里一切都正确返回。不过,正如我所说的,我觉得有点多余,我拿出了then/catch块:

TodoSchema.static('createTodo', async (newTodo: ITodo) => {
    return await Todo.create(newTodo);
});

我得到了这个错误:

(node:1306) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: E11000 duplicate key error index: jaanartc.todos.$slug_1 dup key: { : "test-title" }

据我了解(我在这里可能大错特错),return await Todo.create(newTodo) 应该返回create() 的结果。所以如果我检查instanceof MongoError,我想我应该没问题。

请赐教。谢谢。

【问题讨论】:

  • 仅供参考,return await someFunc() 没有任何理由。它没有添加任何东西。 async 函数已经返回了一个 promise 并且要使用该值,调用者必须自己使用 await.then()。所以,只需return Todo.create(...).then(...)await 仅适用于它所使用的函数内部,不适用于返回值。 async 函数仍然是异步的,并返回一个 promise,它的解析值是你想要的。执行return await someFunc() 确实神奇地允许async 函数直接返回值。它仍然返回一个承诺。
  • 你是对的。感谢您的澄清。

标签: typescript express asynchronous mongoose async-await


【解决方案1】:

在采用 async/await 工作流程时,我认为有两种选择:

TodoSchema.static('createTodo', async (newTodo: ITodo) => {
    return await Todo.create(newTodo);
});

// later on in code
try { const item = await TodoModel.createTodo({...}); }
catch (e) { // do something }

或者

TodoSchema.static('createTodo', async (newTodo: ITodo): Promise<TodoInstance | null> => {
  try { return await Todo.create(newTodo); }
  catch (e) { return null;  }
});

// later on in code
const item = await TodoModel.createTodo({...});

if (!item) {
  // something went wrong
}

item.remove() // this is safe now

我会选择第二种方法,否则会很头疼

【讨论】:

猜你喜欢
  • 2020-11-21
  • 2012-06-29
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 2018-10-25
相关资源
最近更新 更多