JavaScript及ES6|ES6---(3)Promise对象

一、Promise对象介绍 ES6原生提供了Promise对象,它表示未来要发生的事件,相当于一个容器,保存着异步操作的一些结果。各种异步操作都可以用同样的方法进行处理。
特点:

  1. 对象的状态不受外界影响 处理异步操作 三个状态:Pending(进行) Resolved(成功) Rejected(失败)
  2. 一旦状态改变,就不会再次改变,任何时候都可以得到这个结果
二、基本使用 可以使用new来创建一个Promise对象的一个实例。
let prom = new Promise(function(resolved, rejected) { }

Promise包含一个回调函数,有resolve和reject两个参数,如果函数在调用时执行操作正常,则会调用resolve,否则调用reject。
实例
function timeOut(ms) {return new Promise((resolved, rejected) => {setTimeout(() => {resolved("success!!") }, ms); }) } timeOut(2000).then((val) => {console.log(val); })

我们定义一个超时函数,返回一个Promise对象实例,然后我们调用它,.then()方法返回成功的返回值success。
三、用Promise封装Ajax 我们可以用promise封装一个类似于Ajax的函数。
const getJSON = function(url) {// 返回一个promise对象 return new Promise((Resolved, Rejected) => {const xhr = new XMLHttpRequest(); // 打开网址 xhr.open('GET', url); // 状态改变,调用函数 xhr.onreadystatechange = handler; xhr.responseType = 'json'; xhr.setRequestHeader("Accept", 'application/json'); // 发送 xhr.send(); function handler() {// console.log(this.readyState); // console.log(this); if (this.readyState === 4) {if (this.status === 200) {Resolved(this.response); } else {Rejected(new Error(this.statusText)); } } } }) }getJSON("https://api.vvhan.com/api/weather?city=北京&type=week").then( (data) => {console.log(data); }, (error) => {console.log(error); } )

getJSON函数返回一个promise对象实例,在这里我们new一个请求数据的对象,然后判断状态改变(进行->成功 或者 进行->失败),调用handler函数根据状态码判断数据是否获取成功再返回相应内容。
.then().catch()链式编程
// then() 方法 // then() 第一个参数是resolved回调函数,第二个参数可选Rejected状态的回调函数 // then() 返回一个新的Promise对象实例,因此可以采用链式编程,不过实际开发一般采用.catch()方法捕获异常 // getJSON("https://api.vvhan.com/api/weather?city=北京&type=week").then( //(data) => {//console.log(data); //}).catch(err => {//console.log(err); //}) // 这里等价于.then(null, err => {})

四、promise对象其他常用方法 1、resolve()方法
// resolve() 将现有的任何对象转换成promise对象 let p = Promise.resolve("foo"); console.log(p); p.then(data => {console.log(data); // foo })

2、all()方法
【JavaScript及ES6|ES6---(3)Promise对象】应用:一些游戏类的素材比较多,等待图片、静态资源都加载完成才进行页面的初始化。
all()方法有一个数组作为参数,只有当数组内容状态全为成功才会被resolve,否则reject。
let promise1 = new Promise((resolve, reject) => { }); let promise2 = new Promise((resolve, reject) => { }); let promise3 = new Promise((resolve, reject) => { }); let p4 = Promise.all([promise1, promise2, promise3]); p4.then(() => {// 三个都成功才成功 }).catch(err => {// 有一个失败则失败 })

3、race()方法
Promise.race([p1,p2,p3])
当p1,p2,p3状态改变时,先返回状态改变完成的。
应用:给某个异步请求设置超时时间,并且在超时后执行相应的操作。
例如在请求一个图片资源时。
function requestImg(imgSrc) {return new Promise((resolve, reject) => {const img = new Image(); img.onload = function() {resolve(img); } img.src = https://www.it610.com/article/imgSrc; }) }function timeOut() {return new Promise((resolve, reject) => {setTimeout(() => {reject(new Error("图片请求超时")) }, 3000); }) }let src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F10%2F29%2F2ac8e99273bc079e40a8dc079ca11b1f.jpg&refer=http%3A%2F%2Fbpic.588ku.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1634906070&t=c93ae1e0fdaf933291962dc5726bfb9b"; Promise.race([requestImg(src), timeOut()]).then(res => {console.log(res); document.body.appendChild(res); }).catch(err => {console.log(err); })

图片是我随便百度的一张。当requestImg()函数成功获取图片后,返回该图片,把它渲染到页面上,否则就调用timeOut()函数扔出一个错误。
看效果:
JavaScript及ES6|ES6---(3)Promise对象
文章图片

下一篇:ES6—(4)async的用法

    推荐阅读