ES6---(3)Promise对象

x33g5p2x  于2021-09-24 转载在 其他  
字(3.1k)|赞(0)|评价(0)|浏览(446)

一、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()方法

应用:一些游戏类的素材比较多,等待图片、静态资源都加载完成才进行页面的初始化。
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 = 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()函数扔出一个错误。
看效果:

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

相关文章