zoukankan      html  css  js  c++  java
  • JS promise对象

    Promise 承诺

    一:promise概念

      在js中,promise是一个对象,是专门用来处理异步操作 / 回调地狱的,那么什么是回调地狱?涉及到同步和异步任务的知识,在js中,因为js是单线程,无法多并发处理任务,当在js中运行代码时,首先会优先执行同步代码,而异步代码则必须等到同步代码全部执行完才会被执行,那么每个异步代码的加载都需要时间,有快有慢,当我们需求让异步按照我们自己的开发想法来运行,显然需要进行嵌套才能让异步任务有序的按照我们自己的想法执行,就是在这一不断嵌套的过程中,就会形成回调地狱,一不便于管理,代码耦合严重,二代码非常难看,那么promise的出现就解决了这回调地狱的带来的不好的体验。

    二:promise的特点  

      1:在promise中,总共有三种状态,分别是准备中(pending),成功时(resolved)和失败时(rejected)

      2:一但创建,状态立即时pending,只有异步返回的结构可以改变其状态,且只能由pending—>resolved 或者 pending -->rejected,没有其他情况

    三:promise的语法和方法

      (1):使用promise时,需要使用 new 出来

     1 var pms = new Promise(function(resolve,reject){
     2     var i = 3;
     3     if(i>3){
     4         // resolve 表示正确完成时执行的函数
     5         resolve();
     6     }else{
     7         // reject 表示失败时执行的函数
     8         reject();
     9     }
    10 })
    11 // 调用 promise 下的两个回调函数 - then 方法
    12 pms.then(function(){
    13     // 当正确时执行
    14     console.log('执行resolve回调函数');
    15 },function(){
    16     // 当失败时执行
    17     console.log('执行reject回调函数');
    18 })

      Promise对象的回调函数下有两个参数,都是回调函数:第一个参数resolved,第二个参数rejected,分别对应成功状态和失败状态,使用then方法来获取返回的结果和状态。

      Promise的then 方法:promise对象中用来执行回调函数的方法,then方法接受两个参数,第一个是成功的resolved的回调,另一个是失败rejected的回调,且第二个失败的回调参数可选。并且then方法里也可以返回promise对象。

      (2):promise的状态只被执行一次

     1 // promise 状态只能被执行一次
     2 var pms = new Promise(function(resolve,reject){
     3     // 1:在 promise 中 resolve和reject,只能被调用一次,不能同时调用
     4     // 2:当执行resolve或者reject时,这个Promise当中状态就会被修改
     5     resolve(4) // 只执行第一个,后面的不执行
     6     reject(3)
     7     resolve(2)
     8     reject(1)
     9 })
    10 // 调用 promise - then方法
    11 // catch 方法:是promise中执行 promise发生错误时的方法
    12 pms.then(function(num){
    13     console.log(num)  // 4
    14 }).catch(function(num){
    15     console.log(num)
    16 })

      使用promise,他的状态要么从pending改变成resolve,要么就是从pending改变成reject,当在promise中调用多次promise对象的回调,只会执行一次。

      catch 方法是promise中执行 promise发生错误时的方法

      (3):promise的resolve和reject方法

     1 // Promise.resolve() 方法:直接执行Promise的resolve方法,并且传入参数
     2 // 返回一个Promise对象,状态为resolve
     3 // pmsRes 的状态为 resolve
     4 var pmsRes = Promise.resolve(3).then(function(num){
     5     console.log(num); // 3
     6 })
     7 
     8 // Promise.reject() 方法:直接执行Promise的reject方法,并且传入参数
     9 // 返回一个Promise对象,状态为rejected
    10 // pmsRes 的状态为 reject
    11 var pmsRej = Promise.reject(1).then(function(num){
    12     console.log(num); // Uncaught (in promise) 1
    13 })

       (4):promise.all()的方法 - all中的参数是一个数组,数组中放置的时promise对象,只有当数组中所有的都执行成resolve状态,才会执行all方法,注意,一定是所有,有一个是为失败,all方法不会执行,相当于运算符且 &&

     1 function loadImage(src){
     2     var pms = new Promise(function(resolve,reject){
     3         var img = new Image()
     4         // 给 img 添加 load事件 和 error事件,由promies 回调函数返回结果
     5         img.onload = function(){
     6             resolve(img);
     7         } 
     8         img.onerror = function(){
     9             // 当错误时,执行reject
    10             reject(src);
    11         }
    12         // 给img 添加地址 - 在这里为同步代码
    13         img.src = src;
    14     })
    15     // 返回这个 promies 对象
    16     return pms;
    17 }
    18 var arr = [];
    19 for(var i = 0;i < 5;i++){
    20     var res = loadImage('./images/'+i+'.jpg');
    21     arr.push(res);
    22 }
    23 // 当arr数组中所有的都完成了,才会执行all方法
    24 Promise.all(arr).then(function(list){
    25     list.forEach(itme=> {
    26         // 在这里只有图片都完成,才会打印所有图片的宽度
    27         console.log(itme.width);
    28     });
    29 })

    图片格式:

      (5): 连缀式写法,处理回调地狱

     

     1 function loadImage(src){
     2     
     3     var pms = new Promise(function(resolve,reject){
     4         // 创建图片
     5         var img = new Image()
     6         // 给 img 添加 load事件 和 error事件,由promies 回调函数返回结果
     7         img.onload = function(){
     8             // 当正确时,执行resolve
     9             resolve(img);
    10         } 
    11         img.onerror = function(){
    12             // 当错误时,执行reject
    13             reject(src);
    14         }
    15         // 给img 添加地址 - 在这里为同步代码
    16         img.src = src;
    17     })
    18     // 返回这个 promies 对象
    19     return pms;
    20 }
    21 // promies 连缀式写法:结合loadImage函数
    22 // then调用 return 返回下一次的结果
    23 loadImage('./img/5-.jpg').then(function(img){
    24     console.log(img.width,img.src)
    25     return loadImage('./img/6-.jpg');
    26 }).then(function(img){
    27     console.log(img.width,img.src)
    28     return loadImage('./img/7-.jpg');
    29 }).then(function(img){
    30     console.log(img.width,img.src)
    31     return loadImage('./img/8-.jpg');
    32 }).then(function(img){
    33     console.log(img.width,img.src)
    34     return loadImage('./img/9-.jpg');
    35 }).then(function(img){
    36     console.log(img.width,img.src);
    37 })

      如上,通过不断 return 返回promise对象,那么图片的加载就会按照我们自己的想法顺序加载。且比较美观,当图片较多,可以通过循环的方式来返回promise对象,就不需要一直连缀下去了。

      

  • 相关阅读:
    ssize_t与size_t的前世今生
    jQuery 中的事件参数传递机制
    链表的container_of 疑惑
    c 语言使用疑惑小记
    IQueryFilter的WhereClause详解
    给自己鼓励...
    什么是闭包,我的理解
    WCF 第五章 行为 为服务终结点行为实现一个消息检测器
    WCF 第五章 行为 事务之事务服务行为
    WCF 第四章 绑定 wsHttpBinding
  • 原文地址:https://www.cnblogs.com/MnongY/p/13268979.html
Copyright © 2011-2022 走看看