ES6_Promise基础

回调地狱

相信小伙伴们在日常开发中会经常碰到类似开发场景:

     setTimeout(function(){
        console.log('陕西西安');
        setTimeout(function () {
            console.log('广东深圳');
            setTimeout(function () {
                console.log('浙江杭州');
            },1000)
        },2000)
    },3000)

上述场景我们称之为回调地狱。

回调地狱:在回调函数中再嵌套回调函数的情况(是实现代码顺序执行的一种操作方式)
    
        (1)代码的可读性差、可维护性差
        
        (2)代码的扩展性差

Promise简介

Promise 是异步编程的一种解决方案:

从语法上讲,promise是一个对象,从它可以获取异步操作的消息;

从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。

promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态)

状态一旦改变,就不会再变。

创造promise实例后,它会立即执行。

Promise用处

promise是用来解决以下问题:

  1.回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象

  2.promise可以支持多个并发的请求,获取并发请求中的数据

Promise API

创建实例

<script>
    //实例化 Promise 对象
    const p = new Promise(function(resolve, reject){
        setTimeout(function(){
            // let data = '数据库中的用户数据';
            // resolve(data);
            let err = '数据读取失败';
            reject(err);
        }, 1000);
    });

    //调用 promise 对象的 then 方法
    p.then(function(value){
        console.log(value);
    }, function(reason){
        console.error(reason);
    })
</script>
Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:

  resolve :异步操作执行成功后的回调函数

  reject:异步操作执行失败后的回调函数

then方法

调用 then 方法,then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定。
  1. 如果回调函数中返回的结果是非promise类型的属性, 状态为成功, 返回值为对象的成功的值。
  2.如果回调函数中返回的结果是promise对象, 状态为该promise对象中的状态。
  3.如果抛出错误,状态为失败,返回值是对象的失败的值。
<script>
    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('用户数据');
            // reject('出错啦');
        }, 1000)
    });

    const result = p.then(value => {
        console.log(value);
        //1. 非 promise 类型的属性
        // return 'iloveyou';
        //2. 是 promise 对象
        // return new Promise((resolve, reject) => {
        //     resolve('ok');
        //     // reject('error');
        // });
        //3. 抛出错误
        // throw new Error('出错啦!');
        throw '出错啦!';
    }, reason => {
        console.warn(reason);
    }).then(value => {
        console.log(value);
    }, reason => {
        console.warn(reason);
    });
</script>

catch方法

我们知道Promise对象除了then方法,还有一个catch方法,它是做什么用的呢?其实它和then的第二个参数一样,用来指定reject的回调。用法是这样:

<script>
    const p = new Promise((resolve, reject)=>{
        setTimeout(()=>{
            //设置 p 对象的状态为失败, 并设置失败的值
            reject("出错啦!");
        }, 1000)
    });

    // p.then(function(value){}, function(reason){
    //     console.error(reason);
    // });

    p.catch(function(reason){
        console.warn(reason);
    });
</script>

效果和写在then的第二个参数里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。与try/catch语句有相同的功能。

Promise.all方法

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

let Promise1 = new Promise(function(resolve, reject){})
let Promise2 = new Promise(function(resolve, reject){})
let Promise3 = new Promise(function(resolve, reject){})

let p = Promise.all([Promise1, Promise2, Promise3])

p.then(funciton(){
  // 三个都成功则成功  
}, function(){
  // 只要有失败,则失败 
})
有了all,就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。

Promise.race方法

 //请求某个图片资源
    function requestImg(){
        var p = new Promise((resolve, reject) => {
            var img = new Image();
            img.onload = function(){
                resolve(img);
            }
            img.src = '图片的路径';
        });
        return p;
    }
    //延时函数,用于给请求计时
    function timeout(){
        var p = new Promise((resolve, reject) => {
            setTimeout(() => {
                reject('图片请求超时');
            }, 5000);
        });
        return p;
    }
    Promise.race([requestImg(), timeout()]).then((data) =>{
        console.log(data);
    }).catch((err) => {
        console.log(err);
    });
requestImg函数会异步请求一张图片,我把地址写为"图片的路径",所以肯定是无法成功请求到的。timeout函数是一个延时5秒的异步操作。我们把这两个返回Promise对象的函数放进race,于是他俩就会赛跑,如果5秒之内图片请求成功了,那么进入then方法,执行正常的流程。如果5秒钟图片还未成功返回,那么timeout就跑赢了,则进入catch,报出“图片请求超时”的信息。
posted @ 2022-04-20 11:24  城南以南123  阅读(21)  评论(0编辑  收藏  举报