javascript - 什么时候使用await?

标签 javascript asynchronous promise async-await sequelize.js

我正在使用带有 typescript 的sequelize。我知道代码是异步的,并且 在这里,我使用 promise,并且代码有效..

我想知道什么时候必须使用await关键字?

const promises = []
let tabIdDoc = requestedListIdDoc.toString().split(",")

for (let thisIdDoc of tabIdDoc) {
    promises.push(sequelize.models['Document'].findById(thisIdDoc))
}

q.all(promises).then((resultReq) => {        
    const lstDocs = []
    for (let MyDoc of resultReq) {
        if (MyDoc.matriculeDoc != "") {
            lstDocs.push(sequelize.models['FolderDocContent'].findOrCreate({
                where: {                       
                }
            }))
        }
    }

    q.all(lstDocs).then(() => {
        return response.status(201)
    })           
}

这里需要await关键字吗?

最佳答案

您不必使用 await,因为其他使用 .then() 的编程总能完成工作,但有很多时候使用 >await 使您的代码更简单。当您尝试对多个异步操作进行排序时尤其如此,当您需要在后续的多个操作中使用先前的结果时更是如此。

示例 #1:在 for 循环中序列化操作

假设你想将一堆项目保存到数据库中,但是由于各种原因,你需要将它们逐一保存,并且需要按顺序保存(换句话说,你需要对它们进行排序):

async function saveItems(shoppingList) {
    for (let item of shoppingList) {
        // for loop will pause until this promise resolves
        await db.save(item);
    }
}

saveItems(myList).then(() => {
    // all done
}).catch(err => {
    // error here
});

如果不使用 await,您就必须使用更加详细的设计模式,例如 .reduce() 或者在完成时调用的递归函数之前的操作。这是对循环迭代进行排序的更简单的方法。

示例#2:对函数中的不同操作进行排序

假设您需要联系三个不同的外部服务。您需要从其中获取一些数据,然后在进行第二次 API 调用时使用该数据,然后在第三次 API 调用中使用这两个数据:

const rp = require('request-promise');

async function getPrice(productName) {
     // look up productID
     const productID = await rp(`http://service1.com/api/getID?name=${productName}`);
     // use productID to lookup price
     const productPrice = await rp(`http://service1.com/api/getPrice?id=${productID}`);
     // put both productID and price into the shopping cart
     return rp({uri: 'http://service1.com/api/addToCart', body: {name: productName, id: productID}, json: true);
}

getPrice("Nikon_d750").then(total => {
    // all done here, total is new cart total
}).catch(err => {
    // error here
});

这两个示例都需要更多代码才能正确排序异步操作,并且您必须将逻辑嵌套在 .then() 处理程序内。使用 await 指示 JS 解释器自动为您执行嵌套操作。

其他一些例子here on MDN .

使用 await 时要记住的几条规则:

  1. 您只能在以 async 关键字为前缀的函数内使用它,如上面的示例所示。

  2. 所有async函数都会返回一个promise。如果函数中有显式返回值(如 return x),那么当所有异步操作完成时,该值将成为 Promise 的解析值。否则,它只返回一个具有 undefined 解析值的 Promise。因此,要使用异步函数的结果或知道它何时完成,您必须等待该函数的结果(在另一个异步函数内) code> 函数)或者你必须使用 .then()

  3. await 仅暂停包含函数内的执行。就好像函数中的其余代码被放置在一个不可见的 .then() 处理程序中,并且该函数在遇到第一个 await 时仍会立即返回其 Promise >。它不会阻止事件循环或阻止 async 函数之外的其他执行。这让很多人第一次遇到 await 时感到困惑。

  4. 如果您 await 的 promise 被拒绝,那么它会在您的函数中抛出异常。该异常可以通过 try/catch 捕获。如果它没有被捕获,那么异步函数会自动捕获它并拒绝该函数返回的 promise ,其中抛出的值是拒绝原因。第一次使用 await 时,很容易完全忘记您正在等待的 promise 可能会拒绝的错误情况。

关于javascript - 什么时候使用await?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48900838/

相关文章:

javascript - NativeScript - 地理位置 : right way to use getCurrentLocation promise function

jQuery-modal ajax 子项中的 Javascript 失败

javascript - 函数语句需要 AngularJS 服务中的名称

javascript - Bootstrap模式只打开和关闭一次然后就不起作用

c# - 在单元测试中等待异步事件引发事件

javascript - DOM 操作是否异步(当使用浏览器提供的 API 时,如 getElementById 或appendChild)?

java - 谷歌计算 API 支持 promise 吗?

javascript - 有没有办法检查和取消检查我的示例中的 "check-boxes"?

java - 在新线程问题中使用 spring 发送电子邮件

javascript - 总是返回一个 promise 有用吗