zoukankan      html  css  js  c++  java
  • JS之Promise总结

    1. Promise 是异步编程的一种解决方案,主要解决异步操作多的时侯出现的问题:
      1. 异步处理结果顺序不定(如果对处理结果有次序要求的话);
      2. 为解决上面这个问题,那需嵌套异步处理而且要加判断是否成功,这样会导致代码结构复杂,难以维护;
    2. Promise的基本使用:
      1. 实例化 Promise时,要传入一个函数作为参数,通常写成箭头函数:()=>{}
      2. 这个参数又需2个参数,而且也是函数,一个是异步处理成功时调用,另一个是失败时调用,这2个参数通常用resolve和reject命名:(resolve,reject)=>{}这个就是Promise构造函数的参数,这2个函数参数由 JavaScript 引擎提供,不用自己部署,在Promise里直接调用就是,异步处理的结果作为其2个函数的参数;
      3. resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
      4. reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
    3. 然后里面写异步代码,比如ajax请求:(resolve,reject)=>{异步处理,比如ajax请求}
    4. then方法,Promise实例生成以后,再调用这个Promise实例的用then方法,then方法会等待Promise里的异步处理结果才会调用的,其可接受两个回调函数作为参数then(success=>{},error=>{})。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供,或者写到与then平级的catch方法里去处理异常。这两个函数都接受Promise对象传出的值作为参数。
    5. 以上总结有7个函数,用逗号分割描述:Promise构造函数,构造函数的参数也是个函数,resolve函数,reject函数,promise实例的then函数,then的成功函数,then的失败函数(可选)
    6. 又可以继续异步操作,不过是在then方法里的第1个函数里;
    	// 简单应用,仔细看,有7个函数
          const p = new Promise((resolve, reject) => {
            setTimeout(() => {
              resolve("ok123");  //这里传什么,then的第一个函数里就打印什么,这里是传异步结果出去的
              return; //加return,避免resolve(异步结构)后,还执行后面的代码
              console.log("...."); //不会执行
              //如果失败,需手动调用 reject()方法,参数可以自定义传出去,then的第2个函数会接收到
            }, 1000);
          });
          console.log("aaa"); // 1.先打印出来
          p.then(
            (result) => console.log(result), // 2.后打印出来
            (err) => console.log(err) //异常信息打印,这里没异常
          );
    	// 打印结果
    	aaa
    	ok123
    
    1. then方法返回的是一个新的Promise实例,如果返回的是普通值(非Promise对象),then内部也会把结果封装到一个新的Promise对象,以便then后还可以调用then拿到这个普通值,实现链式调用,如果返回的就是Promise对象,那后面自然还可以用then链式调用;
    2. 多次的异步操作用Promise通常用法是:
      1. 创建一个函数;
      2. 在这个函数里先创建一个Promise对象并最终返回return这个Promise对象;
      3. 回头把异步处理写在这个Promise对象里;
      4. 最终呈现的是调用这个函数,返回一个Promise对象,接着再调用其then方法,这时处理了第1个异步操作且结果会在then里得到,在then里再调用这个创建的函数并return出去,这样又返回一个Promise,又可调用then方法,如此链式调用下去,再不考虑异常的情况下(then方法只有一个成功的处理函数作参数):
          //把异步操作(setTimeout)封装到一个Promise对象里,再用一个函数(getData)封装Promise对象,最后返回这个Promise对象
          function getData(url) {
            return new Promise((resolve, reject) => { //返回这个Promise对象
              // 模拟异步处理,实际可能是ajax请求
              setTimeout(() => {
                resolve("异步处理结果:" + url); // 把处理结果通过resovle传出去
              }, Math.ceil(Math.random() * 3) * 1000); //模拟异步操作,耗时在1-3秒内
            });
          }
    
    //最终呈现的效果,3次异步请求按顺序调用并按顺序返回结果,而且代码结构清晰,每次then方法里发起一次异步请求
           getData("第1次请求数据")            //第1次异步请求数据
            .then((res) => {
              //拿到第1次异步处理后得到的数据
              console.log(res);
              return getData("第2次请求数据"); //第2次异步请求数据
            })
            .then((res) => {
              //拿到第2次异步处理后得到的数据
              console.log(res);
              return getData("第3次请求数据"); //第3次异步请求数据
            })
            .then((res) => {
            //拿到第3次异步处理后得到的数据
              console.log(res);
            });
    		//按顺序逐步打印的结果:
    		异步处理结果:第1次请求数据
    		异步处理结果:第2次请求数据
    		异步处理结果:第3次请求数据
    
    1. 通过打印console.dir(Promise);,发现then,catch,finally3个函数是在Promise的原型对象上,所以所有的Promise对象都可以调用这3个函数,而all,allSettled,race,reject,resolve是类方法(有的也称对象方法),只能通过Promise.调用,实例对象不可调用;
      1. Promise.all():并发处理多个任务,只有所有任务都完成才能得到结果;
        • 参数是个Promise对象数组,Promise.all([p1,p2,p3]).then(res => { }),返回结果res也是个数组,对应3个Promise对象的处理结果;
      2. Promise.race(): 并发处理多个任务,只要有一个任务都完成,就能得到结果;
        • 参数是个Promise对象数组,Promise.race([p1,p2,p3]).then(res => { }),返回结果res是3个Promise对象中,最快处理完的那个的结果;
  • 相关阅读:
    红黑树
    二叉搜索树
    散列表
    基本数据结构
    顺序统计量
    RabbitMQ一些实用方法
    (转)elasticsearch连接不到head插件解决方案
    (转)如何优雅的使用rabbit mq
    (转)elasticsearch6.0版本安装head插件
    Rabbit MQ一些参数解释
  • 原文地址:https://www.cnblogs.com/zoulei0718/p/14315560.html
Copyright © 2011-2022 走看看