zoukankan      html  css  js  c++  java
  • 深入解读Promise对象

    promise对象初印象:

    promise对象是异步编程的一种解决方案,传统的方法有回调函数和事件,promise对象是一个容器,保存着未来才会结束的事件的结果

    promise对象有两个特点:

    1.promise对象的状态不受外界因素的影响,promise对象只有三种状态,Pending(进行中)、Resolve(已完成)、Reject(已失败),只有异步操作的结果才能决定是哪一种状态
    2.一旦状态改变,就不会再发生变化,任何时候都可以得到这个结果,promise对象状态变化只有两种可能,从Pending->Resolve、Peding->Reject

    promise新建后就会立即执行:

    所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数
         let promise = new Promise(function (resolve, reject) {
                console.log("promise");
                resolve("当前脚本所有同步任务执行完才会执行"); // resolve()将状态改为resolve,只有执行resolve()才会继续往下走,也就是调用then()
            });
    
            promise.then(function (value) {
                console.log(value);
            });
    
            console.log("顺序执行");
    
            // promise
            // 顺序执行
            // 当前脚本所有同步任务执行完才会执行

    异步加载图:

         function loadImageAsync(url) {
                return new Promise((resolve, reject) => {
                    var img = new Image();
    
                    img.onload = function(){
                        resolve(img);
                    }
                    img.onerror = function(){
                        reject(new Error("Could not load image at"+url));
                    }
    
                    img.src = url;
    
                });
            }
    
            loadImageAsync("./2.png").then((value) => {
                document.body.appendChild(value);
                value.style.border = "solid 5px red";
            });

    使用promise对象实现ajax操作:

        function getJson(url) {
                var promise = new Promise((resolve, reject) => {
                    var xhr = new XMLHttpRequest();
    
                    xhr.open("get", url, true);
    
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState !== 4) {
                            return;
                        }
                        if (this.status === 200) {
                            resolve(this.response);
                        }else{
                            reject(new Error(this.statusText));
                        }
                    }
    
                    xhr.send();
                });
    
                return promise;
            }
    
            getJson("a.txt").then((json) => {
                console.log(json);
            },(error) => {
                console.log("出错了");
            });

    链式操作用法:

         function runAsync1(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步任务1执行完成");
                        resolve("数据1");
                    },2000);
                });
            }
            
            function runAsync2(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步任务2执行完成");
                        resolve("数据2");
                    },2000);
                });
            }
    
            function runAsync3(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步任务3执行完成");
                        resolve("数据3");
                    },2000);
                });
            }
    
            runAsync1().then((data) => {
                console.log(data);
                return runAsync2();
            }).then((data) => {3
                console.log(data);
                return runAsync3();
            }).then((data) => {
                console.log(data);
            });

    reject用法:

         function getNumber(){
                return new Promise((resolve,reject) => {
                    // 做一些异步操作
                    setTimeout(function(){
                        var num = Math.floor(Math.random() * 10);
                        if(num < 5){
                            resolve(num);
                        }else{
                            reject("数字太大了");
                        }
                    },2000);
                });
            } 
    
            getNumber().then((value) => {
                console.log("resolve");
                console.log(value);
            },(error) => {
                console.log("reject");
                console.log(error);
            })

    catch的用法1:代替then()中的第二个参数

         function getNumber() {
                return new Promise((resolve, reject) => {
                    setTimeout(function () {
                        var num = Math.floor(Math.random() * 10);
                        if (num < 5) {
                            resolve(num);
                        } else {
                            reject("数字太大了");
                        }
                    });
                });
            }
    
            getNumber().then((value) => {
                console.log("resolve");
                console.log(value);
            }).catch((error) => {
                console.log("reject");
                console.log(error);
            }) 
     

    catch的用法2:then()中的第一个参数中抛出异常,那么并不会报错卡死js,而跳到catch()中

        function getNumber() {
                return new Promise((resolve, reject) => {
                    setTimeout(function () {
                        var num = Math.floor(Math.random() * 10);
                        if (num < 5) {
                            resolve(num);
                        } else {
                            reject("数字太大了");
                        }
                    });
                });
            }
    
            getNumber().then((value) => {
                console.log("resolve");
                console.log(value);
                console.log(someData);
            }).catch((error) => {
                console.log("reject");
                console.log(error);
            }) 

    all的用法:

    all()接收一个数组作为参数,里面的值最终都返回一个Promise对象,提供了并行执行异步操作的能力,并且在所有异步操作执行完才执行回调,有了all,你就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据,all方法的效果实际上是「谁跑的慢,以谁为准执行回调」
            function runAsync1(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步操作1完成");
                        resolve("data1");
                    },2000);
                });
            }
            
            function runAsync2(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步操作2完成");
                        resolve("data2");
                    },1000);
                });
            }
    
            function runAsync3(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步操作3完成");
                        resolve("data3");
                    },3000);
                });
            }
    
            Promise.all([runAsync1(),runAsync2(),runAsync3()])
            .then((data) => {
                console.log(data);
            });

    race的用法:

    1.race()接收一个数组作为参数,里面的值最终都返回一个Promise对象,提供了并行执行异步操作的能力,race方法的效果是「谁跑的快,以谁为准执行回调」,这就是race方法,这个词本来就是赛跑的意思
         function runAsync1(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步操作1完成");
                        resolve("data1");
                    },1000);
                });
            }
            
            function runAsync2(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步操作2完成");
                        resolve("data2");
                    },2000);
                });
            }
    
            function runAsync3(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        console.log("异步操作3完成");
                        resolve("data3");
                    },3000);
                });
            }
    
            Promise.race([runAsync1(),runAsync2(),runAsync3()])
            .then((data) => {
                console.log(data);
            });

    2.用race给某个异步请求设置超时时间,并且在超时后执行相应的操作:

    function getImg(url){
                return new Promise((resolve,reject) => {
                    var img = new Image();
    
                    img.onload = function(){
                        resolve(img);
                    }
    
                    img.src = "2.png";
                });
            }
    
            function delayTime(){
                return new Promise((resolve,reject) => {
                    setTimeout(function(){
                        reject("图片请求超时了");
                    },5000);
                });
            }
    
            Promise.race([getImg(),delayTime()])
            .then((data) => {
                document.body.appendChild(data);
            }).catch((error) => {
                console.log(error);
            });

    理解Promise.resolve():

    使用Promise.resolve()来创建promise对象,Promise.resolve()的返回值是promise对象
    Promise.resolve("data1").then((value) => {
                console.log(value);
    });

    理解Promise.reject():

    使用Promise.reject()来创建promise对象,Promise.reject()的返回值是promise对象
    Promise.reject(new Error("出错了")).then((value) => {
                console.log(value);
            }).catch((error) => {
                console.log(error);
    });

    每次调用then()和catch()都会返回一个新创建的promise对象:

    案例一:

          var promise1 = new Promise((resolve,reject) => {
                var num = Math.floor(Math.random() * 10);
                if(num < 5){
                    resolve(num);
                }else{
                    reject("数字太大了");
                }
            });
    
            var promise2 = promise1.then((value) => {
                console.log(value);
            });
    
            var promise3 = promise2.catch((error) => {
                console.log(error);
            });
    
            console.log(promise1 !== promise2); // true
            console.log(promise1 !== promise3); // true
            console.log(promise2 !== promise3); // true 

    案例二:

            var promise1 = new Promise((resolve,reject) => {
               resolve(1);
            });
    
            promise1.then((value) => {
                return value * 2;
            });
    
            promise1.then((value) => {
                return value * 2;
            });
    
            promise1.then((value) => {
                console.log("1" + value); // 11
            }); 

    当一个promise对象变为成功状态时后面的promise对象并没有停运:

         function runAsync1() {
                return new Promise((resolve, reject) => {
                    setTimeout(function () {
                        console.log(1);
                        resolve(2);
                    }, 500);
                });
            }
    
            function runAsync2() {
                return new Promise((resolve, reject) => {
                    setTimeout(function () {
                        console.log(3);
                        resolve(4);
                    }, 1000);
                });
            }
    
            Promise.race([runAsync1(), runAsync2()]).then((value) => {
                console.log(value);
            }).catch((error) => {
                console.log(error);
            });
            
            // 1
            // 2
            // 3

    注:

    Promise.prototype.then() -> 返回Promise对象
    Promise.prototype.catch() -> 返回Promise对象
    Promise.prototype.finally() -> 返回Promise对象
    Promise.all() -> 返回Promise实例
    Promise.race() -> 返回Promise实例
    Promise.resolve() -> 返回Promise对象
    Promise.reject() -> 返回Promise对象

  • 相关阅读:
    存储引擎的优缺点及增删改查基本操作
    安装Mariadb
    Mysql 入门概念
    Nginx语法着色
    find用法,文件压缩和lsof和cpio
    软件包管理
    Django 生成六位随机图片验证码
    Django自定义过滤器和自定义标签
    Django零碎知识点
    jQuery实现淡入淡出样式轮播
  • 原文地址:https://www.cnblogs.com/kunmomo/p/9924040.html
Copyright © 2011-2022 走看看