js async await 终极异步解决方案
既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解。
回顾 Promise
Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及其返回的值。
Promise
对象是由关键字 new
及其构造函数来创建的。构造函数会,把一个叫做“处理器函数”(executor function)的函数作为它的参数。这个“处理器函数”接受两个函数resolve
和 reject
作为其参数。当异步任务顺利完成且返回结果值时,会调用 resolve
函数,而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject
函数。
promise 状态
pending:初始状态,既不是成功,也不是失败状态
fulfilled:操作成功
rejected:操作失败
promise demo
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
promise1.then(function(value) {
console.log(value);
// foo
});
console.log(promise1);
// [object Promise]
通过外部then() 方法来绑定成功、失败的回调函数,有没有感觉这个跟之前的ajax 差不多,只不过是我们把回调丢到了then() 中,这个then 并且支持链式操作,即如果存在多个嵌套那么也就是不断的then()。
async await 字面理解
先从字面意思来理解,async 是“异步”的意思,而 await 是等待的意思。所以应该很好理解 async 用于申明一个 异步的function(实际上是async function 对象),而 await 用于等待一个异步任务执行完成的的结果。
并且 await 只能出现在 async 函数中。
async await demo
在api中,把结果return 出去
export async function getRetailUnitPrice () {
const reqBody = await get('/race/spot/racespot/enter/dayahead')
return reqBody
}
vuex 中把结果commit:
// 发电:日前机组中标出力
async getRealTimeRetailUnitPrice ({commit}) {
const {output} = await getRetailUnitPrice()
commit(types.PLANT_REALTIME_DAYAHEAD, {output})
}
在vue中代码
try {this.$store.dispatch('getRealTimeRetailUnitPrice')
} catch (e) {
this.$Message.error(e)
}
async、await 如何执行
async 告诉程序这是一个异步操作,await 是一个操作符,即 await 后面是一个表达式。
async 的返回值
// async
async function testAsync() {
return "hello async";
}
const data = testAsync();
console.log(data);
如图所示:
当调用一个 async 函数时,会返回一个 Promise 对象。根据mdn的解释
当这个 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;
当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。async 函数中可能会有 await 表达式,await表达式会使 async 函数暂停执行,直到表达式中的 Promise 解析完成后继续 执行 async中await 后面的代码并返回解决结果。
注意, await 关键字仅仅在 async function中有效
既然返回的是Promise 对象,所以在最外层不能用 await 获取其返回值的情况下,那么肯定可以用原来的方式:then() 链来处理这个 Promise 对象 如
// async
async function testAsync() {
return "hello async";
}
let data = testAsync().then( (data) => {
console.log(data) // hello async
return data
});
console.log(data);
如果 async 函数没有返回值,又怎么样呢?很容易想到,它会返回 Promise.resolve(undefined)。
联想一下 Promise 的特点无等待,所以在没有 await 的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句。
await 操作符
MDN 是这样描述 await 的:
await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行async function。若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。
阮一峰老师的解释我觉得更容易理解:
async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
按照mdn解释 await会暂停当前async 函数执行,并且await 后面是一个表达式,即这个await 等待的是一个表达式(这个表达式返回promise 对象或者一个具体的值):
- 假如这个表达式如果返回的是一个Promise 对象, 那么它的返回值,实际上就是 Promise 的回调函数 resolve 的参数,如果这个Promise rejected 了,await 表达式会把 Promise 的异常抛出。
- 假如这个表达式如果返回的是一个常量,那么会把这个常量转为Promise.resolve(xx),同理如果没有返回值也是Promise.resolve(underfind)
async function testAwait() {
const data = await "hello await";
console.log(data)
return data
}
输出 “hello await”
返回promose 对象,成功状态
function say() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
let age = 26
resolve(`hello, joel。今年我 ${age} 岁`);
}, 1000);
});
} async function demo() {
const v = await say(); // 输出:hello, joel。今年我 26 岁 等待这个say 的异步,如果成功把回调 resole 函数的参数作为结果
console.log(v);
}
demo();
返回promise 对象,失败状态
function say() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
let age = 26
reject(`hello, joel,发生了异常。今年我 ${age} 岁`);
}, 1000);
});
}
async function demo() {
try {
const v = await say(); // 输出:hello, joel,发生了异常。今年我 26 岁 等待这个say 的异步,如果成功把回调 resole 函数的参数作为结果
console.log(v);
} catch (e) {
console.log(e)
}
}
demo();
async/await 相比原来的Promise的优势在于处理 then 链,不必把回调嵌套在then中,只要await 即可,如
function sing() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(`来一首好听的歌吧~~~`);
}, 1000);
});
}
async function demo() {
try {
const v = await say();
const s = await sing();
console.log(v); // 输出:hello, joel。今年我 26 岁
console.log(s) // 来一首好听的歌吧~~~
} catch (e) {
console.log(e)
}
}
demo();
如果使用原来的Promise 就是把回调放在then()中。
总结
- async 告诉程序这是一个异步,awiat 会暂停执行async中的代码,等待await 表达式后面的结果,跳过async 函数,继续执行后面代码
- async 函数会返回一个Promise 对象,那么当 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值
- await 操作符用于等待一个Promise 对象,并且返回 Promise 对象的处理结果(成功把resolve 函数参数作为await 表达式的值),如果等待的不是 Promise 对象,则用 Promise.resolve(xx) 转化
js async await 终极异步解决方案的更多相关文章
- [转] js async await 终极异步解决方案
阅读目录 回顾 Promise async await 字面理解 async.await 如何执行 await 操作符 总结 既然有了promise 为什么还要有async await ? 当然是pr ...
- [.NET] 利用 async & await 的异步编程
利用 async & await 的异步编程 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/5922573.html 目录 异步编程的简介 异 ...
- [.NET] 利用 async & await 进行异步 IO 操作
利用 async & await 进行异步 IO 操作 [博主]反骨仔 [出处]http://www.cnblogs.com/liqingwen/p/6082673.html 序 上次,博主 ...
- 利用 async & await 的异步编程
走进异步编程的世界 - 开始接触 async/await 利用 async & await 的异步编程 async 的三大返回类型 公司技术需求备忘录
- async+await处理异步问题
在编写网页的时候我们常常会遇到异步问题,async+await是es6提出的解决异步的方法,下面我们来看看这个方法怎么实现解决异步的, 大家都知道,setTimeout是一个定时器.他是一个异步执行的 ...
- Atitit. Async await 优缺点 异步编程的原理and实现 java c# php
Atitit. Async await 优缺点 异步编程的原理and实现 java c# php 1. async & await的来源1 2. 异步编程history1 2.1. 线程池 2 ...
- 使用ES6新特性async await进行异步处理
我们往往在项目中会遇到这样的业务需求,就是首先先进行一个ajax请求,然后再进行下一个ajax请求,而下一个请求需要使用上一个请求得到的数据,请求少了还好说,如果多了,就要一层一层的嵌套,就好像有点c ...
- 深入理解协程(三):async/await实现异步协程
原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的最后一篇. 从本篇你将了解到: ...
- NodeJs通过async/await处理异步
##场景 远古时代 我们在编写express后台,经常要有许多异步IO的处理.在远古时代,我们都是用chunk函数处理,也就是我们最熟悉的那种默认第一个参数是error的函数.我们来模拟一个Mongo ...
随机推荐
- mac下mongoDB的使用
第一步: 我们在网上找到mongoDB的安装文件包,下载下来然后放在mac系统的指定位置,如图所示: 第二步:打开数据库服务端 我们在bin目录下执行mongod这个命令: 首先cd到bin目录 然后 ...
- 对比网络模拟器软件——Cisco Packet Tracer、华为eNSP、H3C Cloud Lab
1.软件介绍 1.1 Cisco Packet Tracer Cisco Packet Tracer(以下简称PT)是一款由思科公司开发的,为网络课程的初学者提供辅助教学的实验模拟器.使用者可以在该模 ...
- Beta冲刺预备
作业链接 Beta冲刺随笔集 github地址 讨论组长是否重选的议题和结论 在Alpha阶段我们由于没有项目经验,很多技术都仅限于书本上的知识,没有真正实践过,所以出现各种各样的问题,在组长的带领下 ...
- [转载] 什么是istio 官网内容
网址:https://preliminary.istio.io/zh/docs/concepts/what-is-istio/ mark 一下 1.0 昨天刚发布. 2018.7.31 Istio 是 ...
- 阿里云视频直播PHP-SDK接入教程
阿里云视频直播PHP-SDK接入教程 阿里云 视频直播 配置 及 PHP-SDK 接入教程 准备工作 域名管理 配置鉴权 地址生成器及DEMO演 ...
- 小程序开发 event对象中 target和currentTarget 属性的区别。
首先本质区别是: event.target返回触发事件的元素 event.currentTarget返回绑定事件的元素 p包含在div内 在outer上点击时,target跟currentTarget ...
- Ubuntu中sublime和Foxit Reader不能使用中文输入法解决方案
虽然Ubuntu下面很多软件同windows下一样,但是经常会出现各种各样的小问题,其中最让人头疼的是软件中的输入法问题. sublime作为一个跨平台的编辑软件,可以支持win,linux和mac系 ...
- Transactional注解中常用参数说明
@Transactional注解中常用参数说明 参 数 名 称 功 能 描 述readOnly ...
- 【设计模式】—— 适配器模式Adapter
前言:[模式总览]——————————by xingoo 模式意图 如果已经有了一种类,而需要调用的接口却并不能通过这个类实现.因此,把这个现有的类,经过适配,转换成支持接口的类. 换句话说,就是把一 ...
- tomcat 启用NIO
从Tomcat6.0以后, Java开发者很容易就可以是用NIO的技术来提升tomcat的并发处理能力. <Connector port="8080" protocol=&q ...