Promise-使用整理

Promise 使用整理

说明

Promise 就是一个对象,用来传递异步操作的信息,他代表某个未来才会知道结果的操作。有了 Promise 就可以将异步操作以同步操作的流程表达出来,避免层层嵌套回调函数

参考 ECMAScript 6 入门

特点

  1. 对象的状态不受外界影响,Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成)、Rejected(已失败),只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法更改这个状态

  2. 一旦状态改变就不会再变化 只能从 Pending 到 Resolved 或者从 Pending 到 Rejected,状态发生后就会一直保持这个结果

1. 创建 Promise 实例

    const getJSON = function (url) {
        const promise = new Promise(function (resolve, reject) {
            /*
                resolve, reject 由 javascript 引擎提供
                resolve:将 Pending(进行中)状态改为 Resolved(已完成)也就是成功时执行,参数可以传递给下一阶段
                reject:将 Pending(进行中)状态改为 Rejected(已失败) 也就是失败时执行,参数同样可以传递下去
            */ 
            // 创建请求对象
            const xhr = new XMLHttpRequest();
            // 建立与服务器链接
            xhr.open('GET', url);
            // 发送请求
            xhr.send();
            // 接受服务器响应
            xhr.onreadystatechange = function () {
                if (this.readyState !== 4) {
                    return;
                }

                if (this.status === 200) {
                    resolve(this.response);
                } else {
                    reject(new Error(this.statusText));
                }
            }
        });

        return promise;
    }
    /*
        .then() 方法可以接受两个参数,
        第一个参数是一个函数,对应 resolve,当状态为 Resolved 时调用,
        第二个参数也是函数,对应 reject ,当状态为 Rejected 时调用,但是一般省略这个参数,错误信息放在 .catch 方法中进行
    */ 
    getJSON('../libs/a.json').then(function (json) {
        console.log(json);
    }, function (error) {
        console.error(error);
    })

2. Promise.prototype.then()

为 Promise 实例添加状态改变后的回调,then() 方法 返回的是一个新的 Promise 实例,可以采用链式语法,指定一组回调函数的执行次序

    getJSON('../libs/a.json').then(function (json) {
        return JSON.parse(json);
    }).then(function (json) {
        console.log(json);
    })

3. Promise.prototype.catch()

用于指定发生错误时的回调,可以捕获错误,

catch() 方法返回的还是一个 Promise 对象,后边可以继续链接 .then() 如果在 catch 之前没有报错,则直接跳过 catch 方法

    getJSON('../libs/a.json').then(function (json) {
        return JSON.parse(json);
    }).then(function (json) {
        console.log(json);
    }).catch(function (error) {
        console.log(error)
    })

4. Promise.all([])

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

  • 参数数组中的元素都需要是 Promise 实例,如果不是,会自动转换成 Promise 实例
  • 只有数组中的 Promise 实例状态都变为‘已完成’ Promise.all() 的状态才会是 ‘已完成’
  • 如果数组中的 Promise 有任何一个的 状态变为 ‘已失败’,Promise.all() 的状态都会变为 ‘已失败’
    const promise = Promise.all([
        getJSON('../libs/a.json').then(res => JSON.parse(res)),
        getJSON('../libs/b.json').then(res => JSON.parse(res)),
        ['aa', 'bb','cc']
    ])
    promise.then(function (res) {
        console.log(res);
        /*
            [                   
                {"name": "a.json"},
                {"name": "b.json"},
                ['aa', 'bb','cc']
            ]
        */ 
    }).catch(function (error) {
        console.log(error)
    })

5. Promise.race([])

与 Promise.all() 方法一样,都是包装一组 Promise 实例为一个新的 Promise 实例

  • 参数数组中只要有一个 实例的状态改变,Promise.race 的状态就会改变成相应的状态
    const promise = Promise.race([
        getJSON('../libs/a.json').then(res => JSON.parse(res)),
        getJSON('../libs/b.json').then(res => JSON.parse(res)),
        ['aa', 'bb','cc']
    ])
    promise.then(function (res) {
        console.log(res);
        /*
            ["aa", "bb", "cc"]
        */ 
    }).catch(function (error) {
        console.log(error)
    })

可以用这个方法设定请求的延迟时间

    const timeout = function () {
        return new Promise(function (resolve, reject) {
            setTimeout(function() {
                reject('timeout');
            }, 5000);
        })
    }

    const promise = Promise.race([
        getJSON('../libs/a.json').then(res => JSON.parse(res)),
        timeout()
    ])
    promise.then(function (res) {
        console.log(res);
        /*
            请求超时 5000 毫秒 就报错
        */ 
    }).catch(function (error) {
        console.log('wrong')
        console.log(error)
    })

6. Promise.resolve()

用来将普通对象转换成 Promise 对象

  1. 参数是 Promise 实例 – 不做修改,直接返回这个实例
  2. 参数是一个具有 then 方法的对象()– 将这个对象转化成 Promise 对象,并立即执行 then 方法
  3. 参数是普通的对象,或者不是对象类型的数据 – 返回一个状态为 Resolved 的 Promise 对象(包含数据)
  4. 不带任何参数 – 返回一个状态为 Resolved 的 Promise 对象(空的)
    // 1. 参数是 Promise 实例
    const a = new Promise(function (resolve) {
        resolve('a');
    })

    const wrapA = Promise.resolve(a);

    wrapA.then(function (res) {
        console.log(res); // a
    })
    console.log(wrapA === a); // true

    // 2. 参数是一个具有 then 方法的对象()
    const b = {
        then: function (resolve) {
            resolve('b')
        }
    }

    const wrapB = Promise.resolve(b);

    wrapB.then(res => {
        console.log(res); // b
    })

    // 3. 参数是普通的对象,或者不是对象类型的数据

    const wrapC = Promise.resolve(['12']);
    wrapC.then(res => {
        console.log(res); // ['12']
    })

    // 4. 不带任何参数
    const wrapD = Promise.resolve();

    wrapD.then((res) => {
        console.log(res); // undefined
    })

7. Promise.reject()

返回一个新的 Promise 实例,该实例的状态为 rejected

    const a = Promise.reject('wrong');

    a.then(res => console.log('in then', res))
        .catch(res => console.log('in catch', res)) // in catch wrong

特性

  • Promise 对象表示未来某个将要发生的事件,但在通过 new 创建的时候,作为参数传入的函数是会被立即执行的

  • then 方法是异步的

    const promise = new Promise(function (resolve, reject) {
        console.log('in Promise constructor');
        resolve('xxx');
        console.log('after resolve');
    })

    console.log('in global');

    promise.then(res => {
        console.log('in then method', res);
    })

    console.log('after then method');
    /*
        // 1. in Promise constructor
        // 作为参数传入的函数会被立即执行

        // 2. after resolve
        // resolve 方法不会中断函数运行

        // 3. in global

        // 4. after then method
        // 5. in then method xxx
        // Promise 对象的 then 方法是异步的,所以先打印出 ‘after then method’
    */ 

更多文章

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值