首页 > 解决方案 > 我应该在这个例子中使用异步等待吗

问题描述

似乎以下示例适用于异步等待,如下所示:

import { db } from '../firebase';

const onAdd = async () => {
    await db.collection('FlashCards').add({
      originalText: newOriginalText,
      translatedText: newTranslatedText,
    });

  };

并且没有像这样的异步等待:

import { db } from '../firebase';

const onAdd = () => {
    db.collection('FlashCards').add({
      originalText: newOriginalText,
      translatedText: newTranslatedText,
    });

  };

我使用哪一个有什么区别吗?在这个例子中使用 async await 有什么改善吗?

标签: javascriptasync-await

解决方案


我建议使用第一个片段。它确实有一个优势 - 如果您愿意,您可以等待onAdd完成。对于第二个示例,您可以执行它并且代码将起作用- 将进行插入,但是您不能等待完成。

这是一个简单的例子:

//simple delayed operation - prints a message after 2 seconds
async function delayedOperation(msg) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("complete:", msg);
      
      resolve();
    }, 2000);
  });
}

//awaiting the operation
async function withAwait() {
  await delayedOperation("with await");
}

//not awaiting the operation
function withoutAwait() {
  delayedOperation("without await");
}

async function main() {
  console.log("before calling withAwait()");
  await withAwait();
  console.log("after calling withAwait()");
  
  console.log("before calling withoutAwait()");
  await withoutAwait();
  console.log("after calling withoutAwait()");
}

main();

如您所见,withoutAwait不能等待本身。问题是它不会产生承诺,main()在延迟操作完成之前withoutAwait()完成。

如果不需要,您始终可以在函数中使用但不使用它:await

async function delayedOperation(msg) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("complete:", msg);
      
      resolve();
    }, 2000);
  });
}

async function withAwait() {
  await delayedOperation("with await");
}

async function main() {
  console.log("before calling withAwait()");
  //not awaiting because we don't care whether it finishes before proceeding
  withAwait(); 
  console.log("after calling withAwait()");
}

main();

但是,检查操作是否完成是个好主意,否则您将无法响应错误,甚至可能不知道它们发生了:

//WILL FAIL!
async function delayedOperation(msg) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {      
      reject(`problem when doing [${msg}]`);
    }, 2000);
  });
}

async function withAwait() {
  await delayedOperation("with await");
}

async function main() {
  console.log("before calling withAwait() and handling the error");
  try {
    await withAwait(); 
  } catch(e) {
    console.error(e);
  }
  console.log("after calling withAwait() and handling the error");
  
  console.log("before calling withAwait() - no handling");
  //not awaiting because we don't care whether it finishes before proceeding
  withAwait(); 
  console.log("after calling withAwait() - no handling");
}

main();

并注意,添加async await添加不会让您正确地await获得函数的结果。

async function delayedOperation(msg) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("complete:", msg);
      
      resolve();
    }, 2000);
  });
}


// async function but not awaiting the operation
async function withoutAwait() {
  delayedOperation("without await");
}

async function main() {
  console.log("before calling withoutAwait()");
  //attempting to await the completion
  await withoutAwait();
  console.log("after calling withoutAwait()");
}

main();

由于 the 的主体withoutAwait()没有awaitthen 它在delayedOperation()返回一个承诺时立即完成,而不是在该承诺完成时完成。


推荐阅读