简体   繁体   English

如何使用 Async/Await 回调 [Javascript, Mongoose]

[英]How to Use Async/Await With Callbacks [Javascript, Mongoose]

I have 3 async functions:我有 3 个异步函数:

ToDoItem.deleteMany({}); // deletes entire collection
ToDoItem.insertMany(itemArray); // adds new items to collection
ToDoItem.find({}); // finds all the items in the collection

This code alone doesn't work well, as they do not follow a consistent order.仅此代码并不能很好地工作,因为它们没有遵循一致的顺序。 Ie the insertion might happen before deletion, which I do not want.即插入可能发生在删除之前,这是我不希望的。

I can use callbacks to chain them together (callback hell), and I can also use.then to chain them together, as they return promises.我可以使用回调将它们链接在一起(回调地狱),我也可以使用.then 将它们链接在一起,因为它们返回承诺。 However, I would like to use async/await.但是,我想使用异步/等待。

Additionally, these functions can be given optional callbacks, for instance:此外,可以为这些函数提供可选的回调,例如:

ToDoItem.find({}, (data) => { 
  console.log(data); 
});

This is useful as I want to see all the data in my DB that matches the query {} (which is all items).这很有用,因为我想查看我的数据库中与查询 {} 匹配的所有数据(即所有项目)。

However I can't figure out how to access these callbacks by using async and await.但是我不知道如何使用异步和等待来访问这些回调。 I can do it via callbacks or.then, but the code is more messy.我可以通过回调 or.then 来完成,但是代码比较乱。 Is there a way to do this?有没有办法做到这一点?

Edit:编辑:

As per Bergi's reply, I have edited my code as such:根据 Bergi 的回复,我编辑了我的代码:

async function setupDatabase() {
  const deleteResult = await ToDoItem.deleteMany({});
  console.log("Items deleted. Delete result:")
  console.log(deleteResult);

  const insertResult = await ToDoItem.insertMany(defaultItems);
  console.log("Items have been added successfully");
  console.log(insertResult);

  const findResult = await ToDoItem.find({});
  console.log("Here are the items:")
  console.log(findResult);
}

Am I correct in thinking that:我的想法是否正确:

  1. deleteResult will now evaluate to be either the deletion confirmation (if successful) or the error (if rejected). deleteResult 现在将评估为删除确认(如果成功)或错误(如果被拒绝)。 And similarly with insertResult and findResult?与 insertResult 和 findResult 类似吗?

  2. What do I do if I want to return the collection found by.find({}), as the function setupDatabase is now async and returns a promise.如果我想返回由 .find({}) 找到的集合,我该怎么办,因为 function setupDatabase 现在是异步的并返回 promise。

  3. If 1) is correct, how do I separate out when I'm getting an error and when I'm getting a result?如果 1) 是正确的,我如何区分出现错误和得到结果的时间?

As per Konrad's response, I have done the following:根据康拉德的回应,我做了以下事情:

async function setupDatabase() {
  const deleteResult = await ToDoItem.deleteMany({});
  console.log("Items deleted. Delete result:")
  console.log(deleteResult);

  const insertResult = await ToDoItem.insertMany(defaultItems);
  console.log("Items have been added successfully");
  console.log(insertResult);

  const findResult = await ToDoItem.find({});
  console.log("Here are the items:")
  console.log(findResult);

  return findResult;
}


app.get("/", function(req, res) {
  (async function() {
    const objectList = await setupDatabase();
    let dataList = [];
    
    for (element of objectList) {
      dataList.push(element.todo);
    }
    res.render("list", {listTitle: "Today", newListItems: dataList});
  }());

My idea was to return the findResult inside the setupDatabase function. But this is actually a promise since the function is async, so I wrapped it in an IIFE inside the.get.我的想法是在 setupDatabase function 中返回 findResult。但这实际上是一个 promise,因为 function 是异步的,所以我将它包装在 .get 中的 IIFE 中。 I then iterated over this list and created dataList which has the actual data I want to render.然后,我遍历此列表并创建了 dataList,其中包含我要呈现的实际数据。

You don't use async / await with callbacks.您不使用带有回调的async / await

You use await with promises, and you should not mix those with callbacks - in particular, MongoDB does not return a promise when you pass a callback.您将await与 promises 结合使用,并且不应将它们与回调混合使用 - 特别是,当您传递回调时,MongoDB 不会返回 promise。 You need to write你需要写

await ToDoItem.deleteMany({}); // deletes entire collection
await ToDoItem.insertMany(itemArray); // adds new items to collection
const data = await ToDoItem.find({});

Am I correct in thinking that [the await expression] will now evaluate to be either the deletion confirmation (if successful) or the error (if rejected)?我认为 [ await表达式] 现在将评估为删除确认(如果成功)或错误(如果被拒绝)是否正确?

No. The result of the await is the successful promise fulfillment value.不会。 await的结果是成功的 promise 实现值。 In case of a promise rejection, the error is thrown as an exception, you can handle it with a try / catch block .如果出现 promise 拒绝,错误将作为异常抛出,您可以使用try / catch块处理它

What do I do if I want to return the collection found by .find({}) , as the function setupDatabase is now async and returns a promise.如果我想返回.find({})找到的集合,我该怎么办,因为 function setupDatabase现在是异步的并返回 promise。

The async / await syntax doesn't change anything. async / await语法不会改变任何东西。 The function was asynchronous before, and it's impossible to immediately return the result , regardless whether you'd use callbacks or promise .then() chaining syntax or await syntax. function 之前是异步的,不可能立即返回结果,无论你使用回调还是 promise .then .then()链接语法或await语法。 Returning a promise is actually desirable - the caller just has to wait for it!返回 promise 实际上是可取的——调用者只需要等待它!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM