Vue中 async 和 await
前言
async 和 await 在 vue 和 .Net 中的用法基本一致。
async 表示该方法是异步的,在 vue 中 async 标记的方法返回一个 promise,在.Net中则返回一个 Task。vue中的 Promise 其实就相当于 .Net 中的 Task。都是任务的概念。
await 用在返回 Promise 或 task 的方法调用前,表示将等待任务的完成。重要的是不会阻塞线程。
同步、异步、阻塞和非组赛
对于这几个概念的解释,通常都是用烧水这个例子。
- 同步阻塞:老张烧水,将水壶放在炉子上,然后站在那里等待水壶烧开。
- 同步非阻塞:老张烧水,将水壶放在炉子上,然后去客厅看电视,然后时不时的去看看水有没有烧开。
- 异步阻塞:老张使用响水壶来烧水,将水壶放在炉子上,然后站在那里等待水壶烧开,但是不用每隔一段时间去看水开,而是水烧开后,水壶会自动通知他。
- 异步非阻塞:老张使用响水壶来烧水,将水壶放在炉子上,然后就去客厅看电视,然后水烧开后,水壶会自动通知他。
同步和异步:
- 同步就是烧水,需要自己去轮询(每隔一段时间看看水烧开了没有)
- 异步就是水烧开了,水壶会自动通知你,你就可以回来处理烧开的水了。
阻塞和非阻塞:
- 阻塞:就是烧水的同时,你不可以去干其它的事情。
- 非阻塞:就是烧水的同时,你可以去干其它事情,比如看电视,上网等等。
阻塞和非阻塞是相对于线程是否被阻塞。
async
在 Vue 中定义一个异步方法很简单,在函数前边加上 async 关键字即可。调用方法则和平时的调用一样。如:
async function getData(){
return "hello world!"
}
console.log(getData())
console.log("虽然我在后边,但是我先执行")
输出结果:
由此我们可以看到 async 返回的是一个 Promise 对象。但是要想获取里面的值,就需要借助 then 的调用链方法去获取。
async function getData(){
return "hello world!"
}
getData().then(result => {
console.log(result)
})
console.log("虽然我在后边,但是我先执行")
输出结果:
这就与我们想要的结果一致。
promise的特点:
- 无等待,在没有 await 的情况下执行 async 函数,它会立即执行,并立即返回一个 Promise 对象。
- 无阻塞,既然是立即返回,那么就不会阻塞后边的代码语句。
await
await 的含义为等待,用于等待一个异步方法的执行完成,只有异步方法执行完成后,才能继续执行后边的操作。
不过按语法说明来解释的话,await 操作符用于等待一个 Promise
对象.
语法:
[返回值] = await 表达式;
表达式:
一个 Promise
对象或任何要等待的值。
返回值:
返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
也就是说 await 可以指定任何对象。
描述:
await 表达式会暂停当前 async function
的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的 resolve 函数参数作为 await 表达式的值,继续执行 async function
。
若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。
另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。
如果返回的是一个Promise对象,await 会阻塞后边的代码,等待 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的结果。
因为会阻塞,所以这也就是为什么 await 需要放在 async 方法中的原因。async 不会造成阻塞,它内部所有的阻塞都被封装在一个Promise 中异步执行。
总结
async 会将后面函数的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。