js的三种异步处理
js的三种异步处理
Promise 对象
- 含义: Promise是异步编程的一种解决方案,
- 优点: 相比传统回调函数和事件更加合理和优雅,Promise是链式编程(后面会详细讲述),有效的解决了令人头痛的回调地狱问题,Promise的结果有成功和失败两种状态,只有异步操作的结果,可以决定当前是哪一种状态,外界的任何操作都无法改变这个状态
- 基本用法:
//ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
const p = new Promise(function(resolve,reject){
if(success){
resolve('成功的结果')
}else{
reject('失败的结果')
}
})
p.then(function (res) {
// 接收resolve传来的数据,做些什么
},function (err) {
// 接收reject传来的数据,做些什么
})
p.catch(function (err) {
// 接收reject传来的数据或者捕捉到then()中的运行报错时,做些什么
})
p.finally(function(){
// 不管什么状态都执行
})
- 常用API
- resolve 返回异步操作成功的结果
- reject 返回异步操作失败的结果
- then 执行Promise状态是成功的操作
- catch 执行Promise状态是失败的操作
- finally 不管Promise状态是成功或失败都执行的操作
- Promise.all
- Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3])
p的状态由p1、p2、p3决定,分成两种情况。
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
Generator 函数
- 含义: Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同,
- 基本用法:
function* helloGenerator() {
yield 'hello';
yield 'Generator';
return 'over';
}
let hw = helloGenerator();
hw.next()//{value:"hello",done:false}
hw.next()//{value:"Generator",done:false}
hw.next()//{value:"over",done:true}
hw.next()//{value:undfined,done:true}
- 特征:
- 一是,function关键字与函数名之间有一个星号;
- 二是,函数体内部使用yield表达式,定义不同的内部状态;
- 三是,通过next方法获取每段状态的返回结果,上面分成4次执行了Gennrator函数,第一次,获取第一个yield函数的返回结果并暂停,done:false,代表函数内的状态还没有执行结束;第二次,同理;第三次,获取return 的返回结果,done:true表示函数内的状态已经执行完毕;第四次,函数内已经没有可以执行的状态,所有返回undfined,同时告诉函数内的状态已经执行完毕;如果函数内没有return,在第三次时返回undfined,done:true表示函数内的状态已经执行完毕
async 函数
- 含义: async 函数是在ES2017 标准中引入的,async使得异步操作变得更加方便,其实他就是Generator 函数的语法糖
- 基本用法:
function get1(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(1)},2000)
})
}
async function getSet(){
const n = await get1()
//const n = await '111'
return n
}
getSet().then(console.log)
- 说明:
- await命令只能用在async函数之中,如果用在普通函数,就会报错。
- await后面是一个Promise对象,如get1 return出去的Promise实例;如果不是 Promise 对象,就直接返回对应的值,如直接返回'111'。
- 1、若Promise 对象, 并且其以值 x 被 fulfilled, 则返回值为 x.
- 2、Promise 对象, 并且其以异常 e 被 rejected, 则抛出异常 e
- async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,如果任何一个await语句后面的 Promise 对象变为reject状态或遇到return,那么整个async函数都会中断执行。
- 另外需要注意的是, await 在等待 Promise 对象时会导致 async function 暂停执行, 一直到 Promise 对象决议之后才会 async function 继续执行.
- 如果我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f().then(v => console.log(v))
- 优点: 相比Generator函数,async函数有如下四点改进
- 内置执行器: Generator 函数的执行必须靠next()进行每一次的模块执行,async自带执行器,只需要和普通函数一样调用即可执行
- **更好的语义:**async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
- 返回值是Promise: async函数的返回值是 Promise 对象,可以用then方法指定下一步的操作;而且async函数完全可以看做多个异步函数的操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖,即Promise.all()的用法
- **更广的适用性:**相较于Generator函数async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)
- 补充
- 多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
//此处省略getFoo(), getBar()两个函数
// 写法一
async function getSet(){
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
return [foo, bar]
}
// 写法二
async function getSet(){
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;
return [foo, bar]
}
*文章参考ECMAScript 6 入门 *
js的三种异步处理的更多相关文章
- 异步加载js的三种方法
js加载时间线 : 它是根据js出生的那一刻开始记录的一系列浏览器按照顺序做的事,形容的就是加载顺序,可以用来优化什么东西,理论基础,背下来. 1.创建Document对象,开始解析web页面.解析H ...
- JavaScript 基础——使用js的三种方式,js中的变量,js中的输出语句,js中的运算符;js中的分支结构
JavaScript 1.是什么:基于浏览器 基于(面向)对象 事件驱动 脚本语言 2.作用:表单验证,减轻服务器压力 添加野面动画效果 动态更改页面内容 Ajax网络请求 () 3.组成部分:ECM ...
- HTML5结合CSS的三种方法+结合JS的三种方法
HTML5+CSS: HTML中应用CSS的三种方法 一.内联 内联样式通过style属性直接套进HTML中去. 示例代码 <pstylepstyle="color:red" ...
- (一)JQuery动态加载js的三种方法
Jquery动态加载js的三种方法如下: 第一种: $.getscript("test.js"); 例如: <script type="text/javascrip ...
- js中三种定义变量 const, var, let 的区别
js中三种定义变量的方式const, var, let的区别 1.const定义的变量不可以修改,而且必须初始化. 1 const b = 2;//正确 2 // const b;//错误,必须初始化 ...
- HTML中使用js的三种方式及优缺点介绍
1.内部js: 在直接在页面的<script></script>标签内写js代码 优点:相对于使用行内js,内部js代码较为集中,与页面结构的实现代码耦合度较低,比较便于维护 ...
- JS高级---三种创建对象的方式
JS高级---三种创建对象的方式 字面量的方式 (实例对象) 调用系统的构造函数 自定义构造函数方式 //创建对象---->实例化一个对象,的同时对属性进行初始化 var per=new Per ...
- js的三种继承方式及其优缺点
[转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...
- JS中三种字符串连接方式及其性能比较
工作中经常会碰到要把2个或多个字符串连接成一个字符串的问题,在JS中处理这类问题一般有三种方法,这里将它们一一列出顺便也对它们的性能做个具体的比较. 第一种方法 用连接符“+”把要连接的字符串连起来 ...
随机推荐
- 【模板】dijkstra与floyd
(我永远喜欢floyd) 温馨提示:与SPFA一起食用效果更佳 传送门:https://www.cnblogs.com/Daz-Os0619/p/11388157.html Floyd 大概思路: 对 ...
- C++中重载函数详解
函数的重载详解 什么时函数重载: 函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数.重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避 ...
- 动画方案 Lottie 学习(二)之实战
代码 $('.success-info-title').append('<p class="normal_finish" id="normal_finish_ani ...
- O029、教你看懂OpenStack日志
参考https://www.cnblogs.com/CloudMan6/p/5456484.html instance 从创建到删除的整个生命周期都是有 Nova 管理的,后面各小节我们以inst ...
- Kendall tau距离(即两个内容相同的数组中逆序数对的数量)(算法》P220 第2.5.3.2小节)
一组排列就是一组N个整数的数组,其中0~N-1的每个数都只出现一次.两个排列之间的 Kendall tau距离就是在两组排列中相对顺序不同的数对的数目.例如,0 3 1 6 2 5 4和1 0 3 6 ...
- Java高并发程序设计学习笔记(四):无锁
转自:https://blog.csdn.net/dataiyangu/article/details/86440836#1__3 1. 无锁类的原理详解简介:1.1. CAS1.2. CPU指令2. ...
- Mac EI 10.11.3 MySQL5.7.11 .dmg 安装(便捷设置,密码重置,卸载)
MySQL 5.7+ 安装成功以后会弹出一个临时密码 后面需要通过临时密码设置新的密码 重置root密码:安装成功后,使用临时密码登陆:敲入命令,mysqladmin -u root -p passw ...
- python 语言
认识程序 程序时根据语言提供的指令按照一定的逻辑顺序对获得的数据进行运算,并最终返回给我们的指令和数据的组合. 低级语言有时叫机器语言或者汇编语言,在我们看来是一串0和1组成的二进制数字,这些数字代表 ...
- kubernetes资源清单之pod
什么是pod? Pod是一组一个或多个容器(例如Docker容器),具有共享的存储/网络,以及有关如何运行这些容器的规范. Pod的内容始终位于同一地点,并在同一时间安排,并在共享上下文中运行. Po ...
- functools:管理函数的工具
介绍 functools模块提供了一些工具来管理或扩展和其他callable对象,从而不必完全重写 修饰符 偏函数partial from functools import partial ''' f ...