• Promise的基本用法,基于Promise处理ajax请求


    前言

    Promise是ES6引入的一个新的语法,专门用于异步编程

    一、JS中的异步编程

    在js中,异步编程有三种

    1、 定时任务

    setInterval(() => {
     // ...
    }, interval);
    setTimeout(() => {
    	// ...
    }, timeout);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、ajax

    $.ajax({
        url,
        data,
        success:function (result){
        	alert(result)
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、 事件回调函数

     //定义主函数,回调函数作为参数
    function A(callback) {
        callback();
        console.log('我是主函数');
    }
    
    //定义回调函数
    function B() {
        setTimeout("console.log('我是回调函数')",2000);//即使此时时间设置为0,也会先输出主函数
    }
    
    //调用主函数,将B传进去
    A(B);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    多次异步调用依赖分析

    ① 多次异步调用的结果顺序不确定
    ② 异步调用结果如果存在依赖必须使用嵌套

    二、Promise

    1、概念

    Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,它可以获取异步操作的消息

    官方:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

    2、优点

    ① 可以避免多层异步调用嵌套问题(回调函数)
    ② Promise 对象提供了简洁的API,使得控制异步操作更加容易

    3、基本用法

    实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务

    new Promise(function(resolve, reject){ })
    
    • 1

    resolve和reject两个参数用于处理成功和失败两种情况

    4、基本逻辑

    如果想让Promise成功执行下去,需要执行resolve,如果让它失败执行下去,需要执行reject
    resolve进then,reject进catch

    var p = new Promise(function(resolve,reject){
    	// 这里用于实现异步任务
    	// 成功时调用resolve()
    	// 失败时调用reject()
    });
    p.then(
       function (data) {
           // 从resolve得到正常结果
           console.log(data);
    })
     .catch( 
       function (info) {
         // 从reject得到错误信息
         console.log(info);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5、小案例

    var p = new Promise(function (resolve, reject) {
      setTimeout(function () {
        var flag = false;
        if (flag) {
          //正常情况下
          resolve("hello");
        } else {
          reject("出错了");
        }
      }, 1000);
    });
    // 方法一
    p.then(
      function (data) {
        console.log(data);
      }).catch( function (info) {
        console.log(info);
      })
    // 方法二
    p.then(
      function (data) {
        console.log(data);
      },function (info) {
        console.log(info);
      })
    
    // 方法一和方法二等效
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    6、终止执行链

    如果想终止在某个执行链的位置,可以用Promise.reject(new Error())

    new Promise(function(resolve, reject) {
        resolve(1)
    }).then(result => {
        return result + 1
    }).then(result => {
        return result + 1
    }).then(result => {
    	// 终止掉程序,不再进入下一个then而是进入catch
      return  Promise.reject(new Error(result + '失败'))
       // return result + 1
    }).then(result => {
        return result + 1
    }).catch(error => {	
        alert(error)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    三、基于Promise处理Ajax请求

    1、封装Promise函数处理原生Ajax请求

    封装Promise函数

    function queryData() {
      return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
          if (xhr.readyState != 4) return; //不做处理
          if (xhr.status == 200) {
            //处理正常的情况
            resolve(xhr, responseText);
          } else {
            //处理异常的情况
            reject("出错了");
          }
        };
        xhr.open("get", "/data");
        xhr.send(null);
      });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2、then参数中的函数返回值

    ① 返回Promise实例对象
    返回的该实例对象会调用下一个then

    queryData("http://localhost:3000/data")
      .then(function (data) {
        console.log(data);
      })
      .catch(function (info) {
        console.log(info);
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ② 返回普通值
    返回的普通值会直接传递给下一个then,通过then参数中函数的参数接收该值

    //发送多个ajax请求并且保证顺序
    queryData("http://localhost:3000/data")
      .then(function (data) {
        console.log(data);
        return qureyData("http://localhost:3000/data1");
      })
      .then(function (data) {
        console.log(data);
        return qureyData("http://localhost:3000/data2");
      })
      .then(function (data) {
        console.log(data);
      });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    四、Promise常用的API

    1、实例方法

    原型中的方法

    方法说明
    .then()得到异步执行任务的正确结果
    .catch()获取异常信息
    .finally()成功与否都会执行
    queryData()
      .then(function (data) {
        console.log(data);
      })
      .catch(function (info) {
        console.log(info);
      })
     .finally(function (info) {
        console.log(info);
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、对象方法

    方法说明
    Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果
    Promise.race()并发处理多个异步任务,只要有一个任务完成就得到结果
    Promise.all([p1,p2,p3]).then(result=>{
      console.log(result);
    })
    
    Promise.race([p1,p2,p3]).then(result=>{
       console.log(result);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  • 相关阅读:
    flink StandAlone 单机部署
    java 版 项目管理工程系统,实现项目全周期管理-源码交付
    【用户画像】将数据迁移到ClickHouse(源码实现)、位图的介绍(bitmap)、位图在用户分群中的应用、位图的使用
    “深入理解机器学习性能评估指标:TP、TN、FP、FN、精确率、召回率、准确率、F1-score和mAP”
    【QT ScrollArea】手势滑动ScrollArea窗口实现
    web前端开发面试集合分享
    背景图片属性
    对角线的输出
    Node 进阶学习
    Redis6 十:使用Jedis连接Redis、使用redis完成手机验证码功能案例
  • 原文地址:https://blog.csdn.net/Vest_er/article/details/127465507