异步请求 - Promise

74 阅读2分钟

从一个案例入手

一个完整的promise案例

function promiseFuncOne() {
    const pInstance = new Promise((resolve,reject) => {
        setTimeout(() => {
            let num = Math.ceil(Math.random()*10);
            let string = '';
            if(num < 5) {
                string = '运行成功,执行resolve方法。num=' + num;
                resolve(string);
            } else {
                string = '运行失败,执行reject方法。num=' + num;
                reject(string);
            }
        })
    });
    return pInstance;
}

// 调用
promiseFuncOne().then(
    function(data) {
        console.log('resolved');
        console.log(data);
    },
    function(data) {
        console.log('rejected');
        console.log(data);
    }
);

// 或者使用then/catch
promiseFuncOne().then(res => {
    console.log(res);
}).catch(res => {
    console.log(res);
});

浅谈同步和异步

同步 - 阻塞无并发

异步 - 无阻塞&高并发

// 异步出现的问题
// 之前处理异步都是通过回调函数的形式实现的
// 深层嵌套 - 容易踏入“回调地狱” (链式调用 - 实现一个功能,依次调用多个API)

Promise的三种状态

1. pending[待定] - 初始状态
2. fulfilled[成功] - 操作成功
3. rejected[被否决] - 操作失败

// 状态变化 【状态一经改变,就凝固,不会再改变了】
pending -> fulfilled:调用resolve方法
pedding -> rejected:调用reject方法

.then()

1. 接收 #两个函数# 作为参数,分别代表fulfilled和rejected
2. .then()返回一个新的Promise实例,所以它可以 #链式调用#
3. 状态响应函数可以返回新的Promise,不返回也可以认为返回了一个null
4. 如果返回新的Promise,那么下一个.then()会在新的Promise状态改变之后执行

链式调用

promiseFuncOne()
    .then(res => {
        console.log(res);
        return new Promise(resolve => {
            setTimeout(() => {
                console.log('then中返回新的Promise对象');
                resolve('新promise对象');
            })
        })
     }).then(res => {
        console.log(res); // 新promise对象
     }).catch(res => {
        console.log(res);
     });

function promiseFuncOne() {
    const pInstance = new Promise((resolve,reject) => {
        setTimeout(() => {
            let num = Math.ceil(Math.random()*10);
            let string = '';
            if(num < 5) {
                string = '运行成功,执行resolve方法。num=' + num;
                resolve(string);
            } else {
                string = '运行失败,执行reject方法。num=' + num;
                reject(string);
            }
        })
    })
    return pInstance;
}
// 与上面的相同,此处实现的是内部调用
promiseFuncOne()
    .then(res => {
        console.log(res);
        return new Promise(resolve => {
            setTimeout(() => {
                console.log('then中返回新的Promise对象');
                resolve('新Promise对象');
            })
        }).then(res => {
         console.log(res); // 新promise对象
      })
     }).catch(res => {
        console.log(res);
     });
promiseFuncOne()
    .then(res => {
        console.log(res);
    }).then(res => {
        console.log('then one');
     // throw new Error('异常'); [T]
    })
    .then(res => {
        console.log('then two');
    })
    .catch(res => {
        console.log(res);
    })
    .then(res => {
        console.log('then three');
    });

// 输出 : then one / then two / then three
// 若是fulfilled状态,执行了resolve,后续的.then()方法都会执行

// 将[T]的注释打开
// 输出:then one / Error: 异常 / then three
# then two跳过 & catch也会返回一个Promise实例,状态为resolved的

错误处理

第一种 - reject + then
第二种 - throw new Error + catch() // 推荐

.testPromise2()
    .then(res => {
        console.log(res);
        throw new Error('错误处理');
    }).then(res => {
        console.log(res);
    })
    .catch(res => {
        console.log(res);
    });

Promise.all()批量执行 | Promise.race()

语法格式

Promise.all([p1,p2,...]);
             
// 所有的子Promise都完成,该Promise才完成,返回值是全部值的数组。 
// 有任何一个失败,该Promise都是失败的,返回第一个失败的子Promise结果。

Promise.race()

// 与all()的区别是,任意一个子Promise完成,该Promise就完成
// 只返回第一个完成的子Promise结果