es6 深入浅出 之Promise的用法以及理解

. 前沿


小编一直在项目中使用promise,,但是对promise理解的不是很透彻,总是模棱两可的,所以用的不是很得心应手,最近幸得与空,好好总结学习一下,经过研究总结下来,发现自己一下清晰了好多,不错很有帮助,不过这里都是我自己的理解,可能还有一些不足的地方,还要多多学习,以后还会更新不足的或者错误的地方。


. 一,首先说一下Promise的概念

Promise是异步编程的一种解决方案,说白了就是一个构造函数,他自己本身有race,all,reject,resolve这几个方法,原型上有then,catch两个方法。

二,Promise对象的特点:

  • 1, 对象的状态不受外界影响,promise对象代表一个异步操作,它有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是(承诺)这个名字的由来。
  • 2, 一旦状态改变就不会在改变,任何时候都可以得到这个结果,promise对象状态改变的过程只能是:从pending变为fulfilled还有从pending变为rejected.也就是说如果状态发生上述变化后,状态就不会在改变了,这个时候我们称之为resolved已定型。
  • 3, 这就是与事件event不同的地方,事件是如果你错过了,再去监听是得不到结果的。

三,Promise的用法:

  • 1, 首先它是一个构造函数,所以每当我们new一个promise实例,就表示一个具体的异步操作,这个构造函数里边有两个参数,分别是:resolve(成功之后的回调函数)reject(失败之后的回调函数)
  • 2,所以说这个异步操作的结果就是失败或者成功,两者都需要回调函数reject/resolve返回,这里要注意的是跟之前的单纯的回调函数不同,不能用return把操作结果返回。要用回调函数,切记。
. 我个人觉得这玩意还是需要举例子比较好理解一点。我在我的项目中写了一个例子,用来理解promise,

接下来我们先new一个Promise对象

//我是在vue项目中
    mounted() {
        let textPromise = new Promise((resolve, reject) => {
            //这个时候我们做一些异步操作
            setTimeout(() => {
                console.log("执行完成我测试的promise");
                resolve('这里的resolve是成功后的回调');
            }, 3000);

        });
    },

执行上面的代码,就会发现控制台直接打出执行完成我测试的promise

这里需要注意的是我只是new了一个对象,并没有调用它,但是我写在里边的异步操作已经执行了,所以说当我们使用Promise时,需要写在一个函数中,在需要的时候再去运行这个函数,举个例子:

        <div  @click="shishi"></div>
methods:{
       shishi() {
          console.log("点击方法被调用");
            this.promiseTest().then((data) => {
                console.log(data);
            })
        },
        promiseTest() {
            let textPromise = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise");
                    resolve('这里的resolve是成功后的回调');
                }, 3000);

            });
            return textPromise;
        },
}

看完上面的代码是不是你自己就有了一些理解了

在promiseTest方法里边 return textPromise;出来这个对象,那么接下来就可以在shishi()方法里边使用Promise对象上的then和catch方法了,这里就表现出来promise的强大之处了。

  • 这个时候你就应该有一些小小的领悟就是原来then里边的函数跟我们平时的一个回调函数是一个意思,它接受resolve传过来的数据,可以在shishi这个点击方法执行完成之后在执行textPromise的回调函数。
  • promise的好处就是当有多层回调时,可以不断的在then方法中继续写promise对象并返回,然后在then方法中进行回调操作。
所以说promise的精髓就是能够简化层层回调,直接在后边链式回调then,比你不断的写callback方法要好的多,也就达到了异步的效果。

所以说promise的正确应用场景是

        <div  @click="shishi"></div>
        methods:{
          shishi() {
            this.promiseTest().then((data) => {
              //这里的data就是promiseTest中textPromise对象中resolve回调方法中返回的值
                console.log(data);
            //然后在这里在把this.promiseTestOne(data);的结果回调给下一个dataOne
        //这里如同回调函数,把第二个的方法传过去才会运行,如果在这里只return,data,那么打印的结果就是
          全是第一个promise里resolve('这里的resolve是成功后的回调');的值。
                return this.promiseTestOne(data);
            }, (reject) => {
                console.log(reject);   //这里就是错误的回调,但是尽量不要写在这里,而是写在catch里
            }).then((dataOne) => {
                //这里的dataOne就是promiseTestOne中textPromise1对象中resolve回调方法中返回的值
                console.log(dataOne);
            }).then((data) =>{
                console.log(data);  //同样这个data还是接受的上个promise中resolve回调的值
                console.log("前边俩方法都调用成功后才会走这个");
            }).catch((data) => {
              //一般情况下你的方法出错不会卡死,而是进入这里。
                console.log(data);   //catch就是用来捕获异常的,所以一般错误都会在这里输出日志
            })
        },
        promiseTest() {
            let textPromise = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise");
                    resolve('这里的resolve是成功后的回调');
                  //下边这段代码会执行在reject或者catch中
                    let a = 10;
                    if (a == 10) {
                        reject('这里的reject是失败后的回调');
                    }
                }, 3000);

            });
            return textPromise;

        },
        promiseTestOne(data) {
           //data是接受的第一个promise中的回调值,方便这个promise使用
            console.log("我是第二个方法" + data + "data 是从promiseTest 的resolve 回调传过来的值");
            let textPromise1 = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise  测试11");
                    resolve('这里的resolve是成功后的回调' + '测试1');
                }, 3000);

            });
            return textPromise1;
        },
}

以上写法就达到了你想在某个接口完全完成之后在调用下一个接口,也就是异步调用,而不是像你之前那样,同步的调用接口。

其实上边的代码跟注释就一同解释了promiserejectresolvethencatch、这几个方法

接下来说一下all方法,all是跟then方法同级的一个方法,该方法提供了并行执行(也就是多个方法可以共存并且同时执行)异步操作的能力,就是说在所有的异步操作执行完成后并且都是成功的情况下才会执行回调。
  • 也就是说all方法不适合我上边举的例子,all方法适合在多个互不相关的方法需要同时执行成功后在执行某方法时使用
    shishi() {
            Promise.all([this.promiseTest(),this.promiseTestOne()]).then((allResult) => {
                  console.log(allResult);
                  console.log("所有的异步操作执行完成后并且都是成功的情况下才会执行回调");
            }).catch((catchResult)=>{
                  console.log(catchResult);
                })
        },
        promiseTest() {
            let textPromise = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise")
                    resolve('这里的resolve是成功后的回调');
                }, 3000);

            });
            return textPromise;
        },
        promiseTestOne() {
            let textPromise1 = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise  测试11");
                    resolve('这里的resolve是成功后的回调' + '测试1');
                }, 3000);

            });
            return textPromise1;
        },

里边的注释看完是不是一目了然。

最后再说一下不常用的race方法

race其实是和all是相反的,就是谁先执行完,就先走谁的回调,举个例子,一目了然

注意我把异步的时间改一下

    shishi() {
            Promise.race([this.promiseTest(),this.promiseTestOne()]).then((allResult) => {
                  console.log(allResult);
                  console.log("谁先执行完,就先走谁的回调");
            }).catch((catchResult)=>{
                  console.log(catchResult);
                })
        },
        promiseTest() {
            let textPromise = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise")
                    resolve('这里的resolve是成功后的回调');
                }, 2000);

            });
            return textPromise;
        },
        promiseTestOne() {
            let textPromise1 = new Promise((resolve, reject) => {
                //这个时候我们做一些异步操作
                setTimeout(() => {
                    console.log("执行完成我测试的promise  测试11");
                    resolve('这里的resolve是成功后的回调' + '测试1');
                }, 5000);

            });
            return textPromise1;
        },

上面的代码执行结果就是2秒的先执行完毕就已经进入到then里面的了,而于此同时,promiseTestOne也就是5秒的并没有停止,还在运行,于是在过三秒后,输出了各自的回调值。

结束语

最后再说一下,race方法的用法,小编很少用到,所以等慢慢接触到在更新,目前常用的5种。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容