美文网首页
Promise 有什么用+学习入门

Promise 有什么用+学习入门

作者: 一个冬季 | 来源:发表于2018-03-13 16:27 被阅读2次

    简介

    最开始我是想了解bluebird,后来发现原来要了解bluebird,就先需要了解Promise,所以本节也是了解Promise的基本用法

    学习这个有什么作用

    1、可以减少很多callback回调的方法,减少层层的嵌套,让代码看起来更加的舒服。
    2、针对代码里面存在异步方法时,可以等到异步方法执行完毕了再继续执行后面代码。

    基本用法

    Promise对象是一个构造函数,当我们要使用Promise,需要new一下

    var promise = new Promise(function(resolve, reject) {
         //这里写你的主要代码
    });
    

    Promise构造函数接受一个函数作为参数,这个函数里面携带了二个方法
    resolve与reject,当我们执行操作成功的时候,我们去调用resolve方法,失败的时候我们调用reject方法。为什么要这样规定呢?因为Promise存在三种状态,分别是
    pending(进行中) ,fulfilled(已成功),rejected(已失败)
    当我们调用promise时候,它就已经是处于进行中了,状态只能从pending-->fulfilled或者是pending-->rejected这二种情况

    function testFunction() {
      return new Promise(function(resolve,reject){
         console.log('你好世界');
      });
    }
    var promise = testFunction();//立即执行
    
    你好世界.png

    可以看出,只要testFunction()方法一但调用,就会立即的执行。

    更进一步then()用法,链式的使用

    我们写代码的时候,代码逻辑程序基本上是从上到下,就像河流一样,从高处往低处流淌。

          function methond1(){
                var p = new Promise(function(resolve, reject){
                    resolve("我是第一个方法");
                });
                return p;
            }
            function methond2(){
                var p = new Promise(function(resolve, reject){
                    resolve("我是第二个方法");
                });
                return p;
            }
            function methond3(){
                var p = new Promise(function(resolve, reject){
                    resolve("我是第三个方法");
                });
                return p;
            }
            function methond4(){
                var p = new Promise(function(resolve, reject){
                    resolve("我是第四个方法");
                });
                return p;
            }
            methond1()
            .then(function(data){
                 console.log(data);
                return methond2();
            })
             .then(function(data){
                 console.log(data);
                return "我不调用第三个方法了";
            }).then(function(data){
                 console.log(data);
                 return methond4();
            }).then(function(data){
                 console.log(data);
            }).then(function(data){
                console.log("德玛西亚");
            }).then(function(data){
                console.log("艾欧里亚");
            });
    
    链式调用.png
    从上面的代码里面可以说明几点:
    1、使用return 可以调用方法,也可以把参数传递到下面
    2、当我把参数放到resolve里面,可以在function(data)里面直接获取到
    3、通过then可以直接链式逻辑写代码
    4、data是上一个逻辑里面的数据
    我们也可以看看其他博主大神写的
    下面我直接复制吕大豹代码,我稍做了修改
    function getNumber() {
                var p = new Promise(function (resolve, reject) {
                    var num = Math.ceil(Math.random() * 10); //生成1-10的随机数
                    if (num <= 8) {
                        resolve(num);
                    } else {
                        reject('数字太大了');
                    }
                });
                return p;
            }
              getNumber().then(function(data){
                        console.log('resolved');
                        console.log(data);
                   },
                    function(reason){
                        console.log('rejected');
                        console.log(reason);
                    }
            );
    
    数字正确调用.png 数字不正确调用.png

    上面的代码可以知道then里面可以写2个方法,第一个方法是成功时候调用,第二个个是失败的时候调用。
    如果我直接.then(),不像上面的代码会怎样呢?

     function methond1() {
            var p = new Promise(function (resolve, reject) {
                 resolve("我是第一个方法");
             });
                return p;
            }
            function methond2() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第二个方法");
                });
                return p;
            }
            function methond3() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第三个方法");
                });
                return p;
            }
            function methond4() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第四个方法");
                });
                return p;
            }
             methond1()
             .then(function(data){
                 console.log(data);
                 return methond2();
             }).then(function(){ //这里我没有data了
                 return "我不调用第三个方法了";
             }).then(function(data){
                 console.log(data);
                 return methond4();
             }).then(function(data){
                 console.log(data);
             }).then(function(data){
                 console.log("德玛西亚");
             }).then(function(data){
                 console.log("艾欧里亚");
             }).catch(function(reason){
                 console.log(reason);
             });
    
    直接then().png

    可以看到方法继续执行,没有受到任何的干扰。

    又如果我注释掉return会怎样?

     methond1()
            .then(function(data){
                  console.log(data);
                  return methond2();
             }).then(function(data){
                  console.log(data);
             //return "我不调用第三个方法了";   这里我注释了
             }).then(function(data){
                  console.log(data);
                  return methond4();
             }).then(function(data){
                  console.log(data);
             }).then(function(data){
                  console.log("德玛西亚");
             }).then(function(data){
                  console.log("艾欧里亚");
             }).catch(function(reason){
                  console.log(reason);
             });
    
    去掉了return.png

    可以看到去掉return后,继续执行代码。

    catch捕获异常

    当我们的程序从上到下一直执行的时候,执行到一半出现异常了,就可以使用catch来捕获

     function runAsync1() {
                var p = new Promise(function (resolve, reject) {
                    //做一些异步操作
                    setTimeout(function () {
                        console.log('异步任务1执行完成');
                        resolve('随便什么数据1');
                    }, 1000);
                });
                return p;
            }
            function runAsync2() {
                var p = new Promise(function (resolve, reject) {
                    //做一些异步操作
                    setTimeout(function () {
                        console.log('异步任务2执行完成');
                        resolve('随便什么数据2');
                    }, 2000);
                });
                return p;
            }
            function runAsync3() {
                var p = new Promise(function (resolve, reject) {
                    //做一些异步操作
                    setTimeout(function () {
                        console.log('异步任务3执行完成');
                        resolve('随便什么数据3');
                    }, 2000);
                });
                return p;
            }
            function methond1() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第一个方法");
                });
                return p;
            }
            function methond2() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第二个方法");
                });
                return p;
            }
            function methond3() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第三个方法");
                });
                return p;
            }
            function methond4() {
                var p = new Promise(function (resolve, reject) {
                    resolve("我是第四个方法");
                });
                return p;
            }
             methond1()
                  .then(function(data){
                   console.log(data);
                   return methond2();
             }).then(function(data){
                   console.log(data);
                   return "我不调用第三个方法了";
             }).then(function(data){
                  console.log(data);
                  console.log(bbbbbbbbbbb); //这里的bbbbbbbbbbb我没有定义它,捕获异常
                  return methond4();
              }).then(function(data){
                  console.log(aaaaaaa);//这里我也没有定义它
             }).then(function(data){
                  console.log("德玛西亚");
             }).then(function(data){
                  console.log("艾欧里亚");
             }).catch(function(reason){//这里是捕获异常
                  console.log(reason);
             });
    
    异常捕获.png

    从上面的图片结果来看我们可以总结下:
    1、当出现程序异常,会直接进入catch。
    2、当出现异常,后面的代码不会继续执行。

    链接中途捕获异常

     methond1()
             .then(function(data){
                 console.log(data);
                 return methond2();
             })
             .then(function(data){
                 console.log(data);
                 return Promise.reject(new Error("啦啦啦啦"));
             }).then(function(data){
                console.log(data);
                return methond4();
             }).then(function(data){
                console.log(data);
             }).then(function(data){
                console.log("德玛西亚");
             }).then(function(data){
                console.log("艾欧里亚");
             }).catch(function(reason){
                 console.log(reason);
             });
    
    链接中途捕获异常.png

    从上面的图片结果来看我们可以总结下:
    1、当链接中途发生异常后续不再执行

    异步全部执行完毕了再回调-->all方法

    Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,比如这

    var promise = Promise.all([pro1,pro2, pro3]);
    

    从上面代码我们知道,他接受一数组,pro1,pro2,pro3 都是要Promise 实例,promise 的状态由pro1,pro2, pro3共同决定,只要有1个失败了,那么就是失败的

        function methond1(){
                var p = new Promise(function (resolve, reject) {
                    setTimeout(console.log("methond1"),2000);
                    resolve("100");
                });
                return p;
            }
        function methond2(){
                var p = new Promise(function (resolve, reject) {
                    setTimeout(console.log("methond2"),2000);
                    resolve("200");
                });
                return p;
            }
        function methond3(){
                var p = new Promise(function (resolve, reject) {
                    setTimeout(console.log("methond3"),2000);
                    resolve("300");
                });
                return p;
            }
       Promise.all([methond1(), methond2(), methond3()])
                    .then(function(results){
                        console.log(results);
                    });
    
    all方法的使用.png

    从最后的结论中,我们可以总结以下
    1、最后的100,200,300的数据显示是一个集合,并且当所有的promise执行完后才显示的。

    then()里面遇见return 后续then()继续执行
           function taskA() {
                console.log("Task A");
            }
            function taskB() {
                console.log("Task B");
                return;  //这里打了return了
                console.log("Task C");
            }
            function onRejected(error) {
                console.log("Catch Error: A or B", error);
            }
            function finalTask() {
                console.log("Final Task");
            }
     var promise = Promise.resolve();
            promise
                    .then(taskA)
                    .then(taskB)
                    .then(finalTask)
                    .catch(onRejected);
    
    后续return继续执行.png
    手动结束/终止链接调用
          function taskA() {
                console.log("Task A");
            }
            function taskB() {
                console.log("Task B");
                return Promise.reject(new Error("手动抛出异常"));
            }
            function onRejected(error) {
                console.log(error)
            }
            function finalTask() {
                console.log("Final Task");
            }
            var promise = Promise.resolve();
            promise
                    .then(taskA)
                    .then(taskB)
                    .then(finalTask)
                    .catch(onRejected);
    
    手动抛异常.png

    我又参考了其他文献新增总结如下

    1. 使用promise.then(onFulfilled, onRejected) 的话
      • onFulfilled 中发生异常的话,在 onRejected 中是捕获不到这个异常的。
    2. promise.then(onFulfilled).catch(onRejected) 的情况下
      • then 中产生的异常能在 .catch 中捕获
    3. .then.catch在本质上是没有区别的
      • 需要分场合使用。

    参考与摘要:
    https://www.cnblogs.com/lvdabao/p/es6-promise-1.html 说的很好这一篇。
    https://wohugb.gitbooks.io/ecmascript-6/content/docs/promise.html 入门

    相关文章

      网友评论

          本文标题:Promise 有什么用+学习入门

          本文链接:https://www.haomeiwen.com/subject/hqkzfftx.html