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对象中,最快处理完的那个的结果;
  • 相关阅读:
    第36课 经典问题解析三
    第35课 函数对象分析
    67. Add Binary
    66. Plus One
    58. Length of Last Word
    53. Maximum Subarray
    38. Count and Say
    35. Search Insert Position
    28. Implement strStr()
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/zoulei0718/p/14315560.html
Copyright © 2011-2022 走看看