首页 > 其他分享 >Promise对象

Promise对象

时间:2024-06-06 14:57:18浏览次数:26  
标签:异步 console log 对象 Promise catch new

Promise 对象使用

Promise 基本认识

Promise 是一个对象,用于表示异步操作的最终完成(或失败)及其结果值。它允许你关联处理程序,这些处理程序将在异步操作成功完成时或者失败时调用,从而避免了更复杂的嵌套回调(即回调地狱)。Promise 对象通常用于执行异步操作,如网络请求、文件操作等。它提供了 .then() 和 .catch() 方法来处理 Fulfilled 和 Rejected 状态的结果。

★ Promise 使用语法

proObj = new Promise((resolved, rejected) => {
        resolved("成功的返回值");
        rejected("失败的返回值");
    });
proObj
    .then("处理成功情况的回调函数", "处理失败情况的回调函数")
    .catch("处理 Promise 失败的情况")

Promise 主要特点

  • 异步操作的代理:
    一个 Promise 对象代表一个可能还未完成,也可能已经完成的异步操作。
    
  • 状态: Promise 对象有三种状态

    • Pending(进行中):初始状态,既不是成功,也不是失败状态。
    • Fulfilled(已成功):意味着操作成功完成。
    • Rejected(已失败):意味着操作失败。
  • 不可变性:

     	Promise的状态一旦确定,就不会再改变。这意味着一个Promise对象要么处于pending状态,要么处于fulfilled状态,要么处于rejected状态,而且它不会同时处于两种状态中。这种不可变性是Promise机制的一个重要特性,它确保了异步操作的结果一旦确定,就不会因为后续的代码执行而发生变化.此外,Promise的状态转换只能从pending到fulfilled或从pending到rejected,不能反向转换。这种单向的状态转换机制有助于避免在异步操作中产生混乱和不可预测的行为
    

Promise 的链式调用

  • 说明
    Promise  允许链式调用 .then() 方法,每个 .then() 可以返回一个新的 Promise,使得异步操作可以顺序执行。
    
  • 示例
    doSomething()
        .then(function(result) {
            return doSomethingElse(result);
        })
        .then(function(newResult) {
            return doThirdThing(newResult);
        })
        .then(function(finalResult) {
            console.log('Got the final result: ' + finalResult);
        })
        .catch(failureCallback);
    
  • 优点
    • 提供了一种更加优雅的方式来处理异步操作。
    • 解决了回调地狱问题,使代码更加清晰和易于维护。
  • 缺点
    • 不能取消 Promise,一旦新建它就会立即执行,无法中途取消。
    • 如果不设置回调函数,Promise 内部抛出的错误不会反映到外部。
    • 当处于 Pending 状态时,无法得知当前进展到哪一个阶段(刚开始还是即将完成)。

Promise 应用场景

  • 1-模拟请求数据
    let pro = new Promise(function (resolved, rejected) {
        // 执行异步操作
        let res = {
            // code: 200,
            // data:{
            //     name:'FL'
            // },
            code: 500,
            error: '服务器错误'
        };
        setTimeout(() => {
            if (res.code === 200) {
                resolved(res.data);
            } else {
                rejected(res.error);
            }
        }, 1000)
    });
    
    
    pro.then((res) => {
        console.log(res);
    }, (error) => {
        console.log(error);
    }).catch(() => console.log('Promise 失败'));
    
  • 2-封装超时时间
    function timeOut(ms) {
        return new Promise((resolved, rejected) => {
            setTimeout(() => {
                resolved('hello promise success!!');
            }, ms);
        })
    }
    
    timeOut(2000).then((res) => {
        console.log(res);
    })
    
  • 3-使用promise封装ajax
    // http://ajax-base-api-t.itheima.net/api/getbooks
    function getJSON(url){
        return new Promise((resolve, reject)=>{
            const xhr = new XMLHttpRequest();
            xhr.open("GET", url);
            // 监控状态
            xhr.onreadystatechange = handler;
            // 声明相应数据类型
            xhr.responseType = "json";
            xhr.setRequestHeader('Accept', 'application/json');
            // 发送请求
            xhr.send();
    
            function handler(){
                console.log(this);
                console.log(this.readyState);
                if(this.readyState === 4){
                    if(this.status === 200){
                        resolve(this.response);
                    }else{
                        reject(new Error(this.statusText));
                    }
                }
            }
        })
    }
    
    // then()返回一个新的promise实例,可以采用链式编程(将上一级的返回值作为下一级的实参)
    var a = getJSON('http://ajax-base-api-t.itheima.net/api/getbooks')
        .then((data)=>{
            console.log(data);
            // 返回值作为下一级then的实参
            return data.data;
        },(error)=>{
            console.log(error);
        })
        .then((twoStageData)=>{
            console.log(twoStageData);
        });
    console.log(a);
    

then 的第二参数与catch区别

在JavaScript中使用 Promise 时,.then() 方法可以接受两个参数:第一个是处理成功情况的回调函数,第二个是处理失败情况的回调函数。而 .catch() 方法则专门用于处理 Promise 失败的情况。虽然这两种方式都可以用来处理错误,但它们之间存在一些重要的区别:

  • .then() 的第二个参数
    • .then() 的作用

      .then() 方法的第二个参数是一个可选的错误处理函数,用于处理 Promise 被拒绝(Rejected)的情况。
      
    • 使用 .then() 的第二个参数处理错误有以下特点:

      • 作用域限制:这个错误处理函数只捕获到该 .then() 前面的错误,如果在 .then() 的第一个回调函数(处理成功的回调)中发生错误,这个错误不会被第二个参数捕获。
      • 链式调用:如果 .then() 的第一个回调函数中发生了错误,而没有提供第二个错误处理函数,这个错误会被传递到链中下一个 .catch().then() 的第二个参数中。
  • .catch()
    • .catch() 的作用

      .catch() 方法专门用来捕获链中前面任何 Promise 的错误。
      promise
          .then(function(value) { /* 处理成功 */ })
          .catch(function(error) { /* 处理所有前面的错误 */ });
      
    • 使用 .catch() 的优点包括:

      • 集中处理错误.catch() 可以捕获链中前面任何 Promise 的错误,包括前面 .then() 中的成功回调里抛出的异常。
      • 提高可读性:使用 .catch() 可以使得错误处理更加集中和明确,代码更易于理解和维护。
  • 结论
    虽然 .then() 的第二个参数和 .catch() 都可以用来处理错误,但推荐使用 .catch(),因为它可以捕获整个链中的错误,使得错误处理更加集中和清晰。此外,使用 .catch() 也可以避免某些由于遗漏错误处理函数而导致的难以追踪的错误。
    

Promise 对象的其他方法

  • resolve() 将现有的任何对象转换成 Promise 对象
    let p = Promise.resolve('foo');
    // 等价于
    // let p = new Promise(resolve => resolve('foo'));
    console.log(p);
    
    p.then((data)=>{
        console.log(data)});
    
  • all() 多个 Promise 对象运行结果的合并处理
    • 应用说明

      一些游戏类的素材比较多,等待图片、flash、静态资源文件都加载完成才进行页面初始化
      
    • 示例

      let promise1 = new Promise((resolve, reject)=>{});
      let promise2 = new Promise((resolve, reject)=>{});
      let promise3 = new Promise((resolve, reject)=>{});
      
      let p4 =  Promise.all([promise1, promise2, promise3]);
      p4.then(()=>{
          // 三个promise都成功, 才执行
      }).catch((err)=>{
          // 有一个promise失败, 就执行
      });
      
  • race()
    • 应用说明

      Promise.race() 是一个 JavaScript 方法,它接受一个 Promise 对象的数组作为输入,并返回一个新的 Promise。这个新的 Promise 将会解决(fulfill)或拒绝(reject)为最先解决或拒绝的输入 Promise 的结果;Promise.race() 是处理多个异步操作中最快一个的结果的有效工具。它在需要快速响应的场景或需要处理多个可能的异步结果时非常有用。
      
    • 使用场景

      • 超时处理:可以与超时逻辑配合使用,比如设置一个时间限制,如果某个操作在指定时间内没有完成,则自动拒绝。
      • 竞争条件:当多个异步操作竞争同一个资源时,只需要结果最快的一个。
      • 错误恢复:可以启动多个相同的异步操作,如果其中一个失败了,其他的仍然可以继续,从而提高系统的健壮性。
    • 示例

      // 应用: 监控图片加载过程, 超过设置的加载时间则停止加载并执行超时处理函数
      function requestImg(imgSrc) {
          return new Promise((resolve, reject)=>{
              // 创建图片对象
              const img = new Image();
              img.onload = function(){
                  resolve(img);
              };
              img.src = imgSrc
          })
      }
      
      function timeOut(){
          return new Promise((resolve, reject)=>{
              setTimeout(()=>{
                  reject('图片请求超时!')
              }, 1000);
          })
      }
      
      Promise.race([requestImg('https://img0.baidu.com/it/u=2020518972,2077284106&fm=253&fmt=auto&app=120&f=JPEG?w=889&h=500'), timeOut()])
          .then(res=>{
          console.log('then');
          console.log(res);
          document.body.appendChild(res);
      }).catch(err=>{
          console.log('catch');
          console.log(err);
      })
      
  • done() finally() 不管请求失败还是成功都会执行的方法

标签:异步,console,log,对象,Promise,catch,new
From: https://www.cnblogs.com/cs-songbai/p/18235139

相关文章

  • 可迭代对象-迭代器-生成器
    可迭代对象能被for循环遍历的元素lists=[1,2,3,4]foriinlists:print(i)生成器是一种特殊的变量斐波那契数列生成器defget_data(num):x=0y=1foriinrange(num):x,y=y,x+yyieldx#返回的是一个yield生成器迭代器能被next函数调用并不断返回下一个值的......
  • “深入探讨Java中的对象拷贝:浅拷贝与深拷贝的差异与应用“
        前言:在Java编程中,深拷贝(DeepCopy)与浅拷贝(ShallowCopy)是两个非常重要的概念。它们涉及到对象在内存中的复制方式,对于理解对象的引用、内存管理以及数据安全都至关重要。✨✨✨这里是秋刀鱼不做梦的BLOG✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-C......
  • 在 Powershell 管道中创建新对象
    我希望将某些文件递归复制到目标目录,但保持相同的文件夹结构。我希望能够执行以下操作:gci-Recurse-File*.csproj|rvpa-Relative|select{@{src=$_;dst=[System.IO.Path]::GetDirectoryName($baseDir+$_)}}}|%{mkdir$_.dst&&cp$_.src$_.dst}......
  • tapPromise 函数 (绑定hooks方法)tapable 库,创建自定义插件的库
    tapPromise函数(绑定hooks方法)tapable库,创建自定义插件的库刚看到了一个插件的use函数//引入组件use(plugin:IPluginClass,options?:IPluginOption){if(this._checkPlugin(plugin)&&this.canvas){this._saveCustomAttr(plugin);constpluginRu......
  • Yii2 框架中,通过 yii\db\Command 对象来执行原生 SQL 语句
    在Yii2中,你可以通过yii\db\Command对象来执行原生SQL语句。这包括查询操作(如SELECT)和数据操作(如INSERT、UPDATE、DELETE)。以下是一些常见的例子,展示如何在Yii2中执行SQL语句。执行查询语句执行SELECT查询并获取结果你可以使用queryAll()、queryOne()、queryColu......
  • 【Web API DOM10】日期(时间)对象
    一:实例化1获取系统当前时间即创建日期对象constdate=newDate()console.log(date)2024年6月5日周三 2获取指定的时间以获取2025年6月29日为例constdate=newDate('2025-6-29')console.log(date)二:日期对象方法1使用场景:日期对象返回数据如上图,无法直接使......
  • 面向对象设计方法Review-02.抽象数据类型
    结构化开发方法基本思想:自顶向下,逐步求精,过程抽象,模块化技术概念:结构化程序设计:按照一定的原则与原理,组织编写正确且易读的程序的软件技术。结构化分析设计:数据流图、数据字典、模块结构图。优势:合理性(管理复杂性的有效手段:分解,抽象,层次)、正确性(依据规约,完成任务)程序&......
  • 面向对象设计方法Review-01.课程概述
    课程简介能带来什么:1.掌握OOP基本原理;2.了解OOP新兴技术;3.满足OOP技术需求;课程目标:1.OOPL写代码→OOP→OOSC;2.朴素OOP→系统化OOP;3.传统OO技术→现代化OO技术;课程内容:OO的起源及动机;OO的设计:1.契约式设计;2.设计原则;3.设计模式;4.应用框架;背景概述软......
  • 阿里云OSS对象存储怎么开通?怎么设置APIAccessKey申请教程?
    阿里云OSS对象存储怎么开通?怎么设置APIAccessKey申请教程?阿里云的产品线众多,后台功能复杂,聚搜云有时候找一些产品或者功能的时候,也是找的云里雾里。比如聚搜云这次需要用到阿里云OSS,我们都知道国内的带宽是小水管,如果用来常规的建站用途,其实也没什么大问题,但是如果静态资源......
  • 【鸿蒙】---鸿蒙Next小课堂之Promise
    前言Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。简而言之:Promise用来管理异步,方便编码。这时候该有人要问了,怎么区分异步和同步呢?同步代码:逐行执行,需原地等待结果后,才继续向下执行。异步代码:调用后耗时,不阻塞......