ES6—异步解决方案

Promise对象

是一种异步编程解决方案,Promise是一个容器,保存着将来才会执行的代码;从语法角度来说Promise是一个对象,可以用来获取异步操作的消息。
异步操作,同步解决,避免了层层嵌套的回调函数

特点
Promise对象代表一个异步操作,有三种状态:
pending(进行中)、fulfilled(已成功)、rejected(已失败)
状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固不会再变了,会一直保持这个结果,最后就返回 resolved(已定型)结果。

实例化和实例方法
Promise构造函数接收一个函数作为参数,也就是回调函数;该函数有两个参数,分别是resolve和reject。resolve作为成功的回调函数,reject作为失败的回调函数。

实例方法:
定义在Promise.prototype中的方法,通过Promise的实例可以直接调用

  1. .then()状态由pending=>fulfilled的时候(异步操作成功之后)执行该回调函数
    参数:回调函数,回调函数的参数为resolve函数传递过来的值
    返回值:返回一个新的Promise实例对象,因此可以使用链式调用
  2. .catch()状态由pending=>rejected的时候(异步操作失败之后)执行该回调函数
    参数:回调函数,回调函数的参数为reject函数传递过来的值
    返回值:返回一个新的Promise实例对象,因此可以使用链式调用
  3. .finally()无论异步操作执行成功失败与否,都会执行该回调
    参数:回调函数(回调函数没有参数)
    返回值:返回一个新的Promise实例对象
let p1=new Promise(function(resolve,reject){
    if(1>0){
        resolve("成功");
    }else{
        reject("失败");
    }
})
p1.then((res)=>{
    console.log(res);
}).catch((err)=>{
    console.log(err);
})
//成功

let p2=new Promise((resolve,reject)=>{
    setTimeout(()=>{
        let data='用户的数据';
        resolve(data); //调用resolve之后,对象状态变为成功
        // reject('数据读取失败');
    },1000);
})
//then()如果有两个参数,则第一个参数表示成功的回调,第二个表示失败的回调
p2.then((res)=>{
    console.log(res);
},(err)=>{
    console.log(err);
})
//用户的数据

静态方法
定义在Promise中的方法,通过Promise可以直接调用

方法作用参数返回值
Promise.all([p1,p2])用于将多个 Promise 实例,包装成一个新的 Promise 实例数组,数组中的元素为Promise实例Promise实例,当p1,p2状态都为fulfilled时候,该实例的状态才为fulfilled,此时p1,p2的返回值组成一个数组,传递给该实例的回调函数;只要p1,p2的返回值有一个变为rejected,该实例状态为rejected;
Promise.any([p1,p2])用于将多个 Promise 实例,包装成一个新的 Promise 实例数组,数组中的元素为Promise实例Promise实例,只要p1,p2状态有一个变为fulfilled,该实例的状态为fulfilled;p1,p2状态都变为rejected,该实例状态才为rejected
Promise.race([p1,p2])用于将多个 Promise 实例,包装成一个新的 Promise 实例数组,数组中的元素为Promise实例Promise实例,当p1,p2之中有一个实例率先改变状态,该实例的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给该实例的回调函数。
Promise.resolve()用于将现有对象转化为Promise实例任意值
Promise.reject()返回一个新的 Promise 实例,该实例的状态为rejected错误信息

promise封装ajax请求

迭代器

迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口(对象中的一个属性),就可以完成遍历操作。

原生具备iterator接口的数据(可用for of遍历):
Array , Arguments , Set , Map , String , TypedArray , NodeList

Iterator的作用:
1)为各种数据结构,提供一个统一的、简便的访问接口
2)使得数据结构的成员能够按某种次序排列
3)ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费

遍历过程:
1)创建一个指针对象,指向当前数据结构的起始位置。遍历器对象本质上就是一个指针对象。
2) 第一次调用指针对象的next()方法,可以将指针指向数据结构的第一个成员。
3)接下来不断调用next()方法,指针一直往后移动,直到指向最后一个成员
4)每调用next()方法返回一个包含value和done属性的对象

let arr1=['tom','vicky','jacky'];
let values=arr1.values();
console.log(values.next());	 //{ value: 'tom', done: false }
console.log(values.next()); //{ value: 'vicky', done: false }
console.log(values.next()); //{ value: 'jacky', done: false }
console.log(values.next()); //{ value: undefined, done: true }
//done属性是一个布尔值,表示是否遍历结束,false表示还没有结束,true表示结束

Generator 函数

简介
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同;
简单的把Generator 理解为一个状态机,封装了多个内部状态。执行Generator 函数会返回一个迭代器对象,可以通过调用迭代器next依次遍历Generator函数内部的每一个状态。

特征
1)function关键字与函数名之间有个星号
2)函数内部使用yield表达式

function* myGenFun(){
	console.log('状态一');
    yield 'hello';
    console.log('状态二');
    yield 'world';
    console.log('状态三');
    return 'ending'; //return标志该函数的结束
}
//generator函数的执行结果是一个迭代器对象
let result=myGenFun();
console.log(result);
console.log(result.next());
console.log(result.next());
console.log(result.next());
//打印结果:
//Object [Generator] {}
//状态一
//{ value: 'hello', done: false }
//状态二
//{ value: 'world', done: false }
//状态三
//{ value: 'ending', done: true }

上面的代码有三个状态:'hello' 'world' 'ending'
Generator 函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个迭代器对象,调用遍历器对象的next方法,使得指针移向下一个状态。

每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。也就是说,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。

上面的代码一共调用了四次next方法:
next()第一次调用:Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束。
next()第二次调用:Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值world,done属性的值false,表示遍历还没有结束。
next()第三次调用:Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束),next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined);此时done为ture,表示遍历结束。

参数
在generator函数中可以传递参数,next()方法可以传入实参,这个实参就是前一个yield语句的整体返回结果

function* gen(arg){
    console.log(arg);
    let one=yield 111;

    console.log(one);
    let two=yield 222;
    console.log(two);

    let three=yield 333;
    console.log(three);

}
let result=gen('hello world'); 
result.next(); //hello world	执行到第一个yield
result.next('AAA'); //AAA	执行到第二个yield,传递的实参AAA是第一个yield的返回结果
result.next('BBB');
result.next();

async和await

async用于申明函数是异步,await用于等待一个异步方法执行完成

async函数
ES2017 标准引入了 async 函数,使得异步操作变得更加方便
async函数是 Generator 函数的语法糖,与await配合使用;异步编程,同步处理
1)async函数返回一个 Promise 对象,return语句返回的值,会成为then方法回调函数的参数
2)async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到

await
1)await必须写在async函数中
2)await命令后面是一个 Promise 对象,如果不是,会被转成一个resolve的Promise对象
3)await返回结果就是其后面Promise执行的结果,可能是resolved或者rejected的值

区别
async函数对比 Generator 函数的优点:
1)async函数内部自带执行器
2)更好的语义;async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果
3)更广的适用性;async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)
4)返回值是 Promise;async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值