Promise的介绍和api

931 阅读3分钟

promise 介绍与使用

promise

是一步编程的一种解决方案,比较传统的解决方案回调函数,更合理和更强大。ES6将其写进了语言标准,统一了用法,原生提供了Promise对象

  • 指定回调函数方式更灵活易懂
  • 解决异步回调地狱的问题

回调地狱

  • 当一个回调函数嵌套一个回调函数的时候
  • 就会出现一个嵌套结构
  • 当嵌套的多了就会出现回调地狱情况
  • 比如说我们发送三个ajax请求
    • 第一个正常发送
    • 第二个请求需要第一个请求的结果中的某一个值作为参数
    • 第三个请求需要第二个请求的结果中的某一个值作为参数

promise 基本应用

`.then`: 两个参数,成功的返回值、失败的返回值
`.catch`: 一个参数,失败的返回值
// 接受参数exexcutor 执行器
const mypro = new Promise((resolve, reject) => {
    // 返回成功
    resolve()
    // 返回失败
    reject()
})

mypro.then((res) => {
    // 成功
}, (err) => {
 // 失败 reject()
})
// 失败 reject()
mypro.catch((e) =< {
})

同时存在then的失败回调函数和catch。只会执行then的回调函数

promise 对象状态

Promise 对象通过自身的状态,来控制异步操作。Promise实例具有三种状态

  • pengding 异步操作未完成
  • fulfilled 异步操作成功
  • rejected 异步操作失败

这三种状态的变化途径只有两种

  • 从pengding 到 fulfilled
  • 从pengding 到 rejected

一旦状态变化,就不会再有新的变化。

简单封装ajax

function ajax(url) {
            console.log(url);
            return new Promise ((resolve, reject) => {
                let xhr = new XMLHttpRequest();
                // open - 请求方法, url地址, 是不是异步
                xhr.open("get", url, true);
                xhr.send();
                // 监听回来的结果
                xhr.onreadystatechange = function () {
                    if(xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status < 300){
                            //  成功
                            resolve(JSON.parse(xhr.responseText))
                        } else {
                            // 失败
                            reject(xhr.responseText)
                        }
                    }
                }
            })
        }

        ajax("https://xiongmaoyouxuan.com/api/tabs").then(res => {
            // 请求成功
            console.log('请求成功', res);
        }).catch(error => {
            //  请求失败
            console.error('请求失败', error);
        })
    

对象方法

 Promise 是一个对象方法

1. Promise.resolve

将现有对象转为Promise对象

    Promise.resolve("aaa");
    // 等价于
    new Promise(resolve => resolve("aaa"))

2. Promise.reject

参数也可以是一个promise对象

const p = Promise.reject("error")
// 等价于
const p = new Promise((resolve, reject) =>reject("error"))

3. Promise.then

可做链式调用

then函数中,不return时,默认返回return undefine, fulfilled。并将新的promise的状态改为return的结果

4. Promise.all

方法用于将多个Promise实例,包装成一个新的Promise实例

const p = Promise.all([p1, p2, p3])

可用于forEach循环中使用异步调用,只有全部返回成功才可以走到成功,否则就会到失败。返回的是一个结果数组/

6. Promise.race

将多个Promise实例,包装成一个新的Promise实例

const p = Promise.race([p1, p2, p3])

p1,p2,p3中有一个实例率先改变状态,p的状态就跟着改变,那个率先改变的Promise实例的返回值,就传递给p的回调函数。

可用于请求超时的的请求功能

const p1 = ajax("https://xiongmaoyouxuan.com/api/tabs");
const p2 = new Promise((resolve, reject) => {
 setTimeout(() => {
     reject("超时!");
 }, 2000)
})

Promise.race([p1, p2]).then(res => {
    console.log(res)'
}).catch(err => {
    console.error(err)
})

7. Promise.allSettled

用来确定一组异步操作是否都结束了(不管成功或者失败)。

const p1 = ajax("https://xiongmaoyouxuan.com/api/tabs");
const p2 = new Promise((resolve, reject) => {
 setTimeout(() => {
     reject("超时!");
 }, 2000)
})
Promise.allSettled([p1, p2]).then(res => {
    console.log(res) // 是一个返回的数组,包括状态和返回结果
}).catch(err => {
    console.error(err)
})

返回结果 image.png

8. Promise.any

只要有一个实例变成fulfilled状态,实例就会变成fulfilled状态。如果所有参数实例都便成为rejected状态,包装实例就会变成rejected状态。

const p1 = new Promise((resolve, reject) => {
            setTimeout(_ => {
                reject("11111");
            }, 1000)
        })
        const p2 = new Promise((resolve, reject) => {
            setTimeout(_ => {
                reject("22222");
            }, 2000)
        })

        const p3 = new Promise((resolve, reject) => {
            setTimeout(_ => {
                resolve("33333");
            }, 3000)
        })
        promise.any([p1, p2, p3]).then(res => {
            console.log(res);
        }).catch(err => {
            console.error(err);
        })
        // 3秒后返回'33333'

如果有返回fulfilled状态状态的时候,谁跑的快,then就返回谁的返回值。

finally()

不管任何状态改变都会触发finally()。