细说 Promise 方法

发布于 2022-11-12 20:27:24 字数 4372 浏览 154 评论 0

1.概述

在 Promise 之前,我们 js 解决异步的方式是采用回调函数的方式,但是这种方式有个问题,就是当业务比较复杂时,很容易出现回调地狱,使得代码很难理解和维护。所以,Promise 就是解决回调地狱的问题而出现的异步编程的解决方案。

2.详述 Promise

我们先通过一个简单的例子,来感受一下 Promise。

let p = new Promise(function(resolve,reject){
    
    if(异步操作成功){
        resolve();
    }else{
        reject();
    }
    
});

通过上面的简短的例子中,只需要注意三个地方:Promise(),resolve(),reject()

2.1 Promise()

Promise() 构造函数在 new 的时候,会传递一个函数作为参数,那么这个函数在新建一个 Promise 后,就会立即执行。

let p = new Promise(function(resolve,reject){
    console.log(1);
});
console.log(2);
// 1
// 2

2.2 Promise 的三种状态

Promise 对象有三种状态:pending(进行中),resolved(已完成),rejected(已失败)。

一旦状态由 pending 变成了resolved了,状态就凝固了,不会再改变了,会一直保持这个状态。一旦状态由pending变成了rejected了,状态就凝固了,也不会再改变了。

在声明一个Promise对象实例时,我们传入的函数参数中,resolve对应着完成态之后的操作,reject对应着失败态之后的操作。

2.3 then() 方法

then()方法是Promise实例上的方法,then()方法是异步的方法,需要自己调用,调用时传递两个参数:第一个参数(函数)对应着完成态的操作,也就是resolve。第二个参数(函数)对应着失败态的操作,也就是reject。

也就是说,在Promise中是通过then()方法来指定处理异步操作结果的方法。

then()方法的返回值是什么呐?then方法会返回一个新的Promise实例,这样的设计好处是可以使用链式写法,还有一点是链式写法中的then方法(第二个开始),它们的resolve中的参数是什么呐?就是前一个then()中的resolve的return返回值。

let p1 = new Promise(function(resolve,reject){
    setTimeout(()=>{
        resolve('p1');
    },10);
});
p1.then(data=>{
    console.log(data);  //p1
    return'then1';
}).then(data=>{
    console.log(data);  //then1
    return'then2';
}).then(data=>{
    console.log(data);  //then2
});

2.4 示例

function loadImage(url){
    return new Promise(function(resolve,reject){
        let img = new Image();
        img.src = url;
        img.onload = function(){
            resolve();
        }
        img.onerror = function(){
            reject();
        }
    });
}

let img1 = loadImage("https://www.wenjiangs.com/wp-content/uploads/2022/docimg20/345-howc2kjwddb.jpg");
img1.then(function(data){
    console.log("success");
},function(err){
    console.log("error");
});

3.Promise 进阶

reject 函数的参数一般是一个 Error 对象的实例,而 resolve 函数的参数除了是正常 return 返回的值之外,还有可能是一个 Promise 实例。

let p1 = new Promise(function(resolve,reject){
    setTimeout(()=>{
        resolve('hello');
    },3000);
});
let p2 = new Promise(function(resolve,reject){
    setTimeout(()=>{
        resolve(p1);
    },10);
});
p2.then((data)=>{
    console.log(data);
});

p2会等待p1的执行结果,然后再执行,输出的结果是hello,从输出的结果可知,p1完成状态转变之后,传递给resolve(或者reject)的结果会传递给p2中的resolve。

4.catch() 错误处理

catch()方法是Promise原型上的方法,用于指定发生错误时的回调。

let p = new Promise(function(resolve,reject){
    setTimeout(()=>{
        resolve('p1');
    },0);
});
p.then((data)=>{
    console.log(data);
    throw new Error('then1');
    return'then1';
}).then((data)=>{
    console.log(data);
    throw new Error('then2');
    return'then2';
}).catch(err=>{     //在此处可以捕获前面的错误
    console.log(err);   
});

执行结果是:

p1
then1

可以看出,在第一个then中抛出了一个错误,在最后一个Promise对象中可以catch到这个错误,所以,一般我们就不用在then方法中指定reject状态的回调函数了,而是指定catch方法即可。

5.all() 方法

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

// task1
functiontask1(){
    console.log("task1");
    let p = new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log('set-01');
            resolve('then1');
        },1000);
    });
    return p;
}
// task2
functiontask2(){
    console.log('task2');
    let p = new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log('set-02');
            resolve('then2');
        },1000);
    });
    return p;
}
Promise.all([task1(),task2()]).then((data)=>{
    console.log('done');
    console.log(data);
});

运行结果是:

task1
task2
set-01
set-02
done
['then1','then2']

6. race() 方法

race() 从字面意思就知道是赛跑的意思,其用法和 all() 方法相同,但是二者的区别是all()方法是全部的异步操作都执行完毕后,才执行 then 回调;而 race() 方法是只要有一个异步操作执行完毕后,就立即执行 then 回调,需要注意的是,其它没有执行完毕的异步操作仍然会继续执行,而不是停止了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

溺深海

暂无简介

文章
评论
28 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文