ES6中promise的使用

news2024/11/15 11:13:26

ES6中promise的使用

本文目录

    • ES6中promise的使用
      • 基础介绍
        • 箭头函数
        • function函数
        • 状态
      • 原型方法
        • Promise.prototype.then()
        • Promise.prototype.catch()
      • 静态方法
        • Promise.all()
        • Promise.race()
        • Promise.any()
      • 链式回调

基础介绍

官网:https://promisesaplus.com/

window.Promise

箭头函数

let p1 = new Promise((resolved, rejected) => {
  console.log("p1 Promise");
})
console.log(p1);

function函数

let p2 = new Promise(function (resolve, reject) {
  console.log("p2 Promise");
});
console.log(p2);

new Promise函数是同步函数,是立即执行的

状态

promise共有三种状态:pending / fulfilled / rejected

状态转换

  • pending -> fulfilled:成功状态
  • pending -> rejected:失败状态
let p = new Promise((resolved, rejected) => {
  console.log("p Promise");
  // resolved()
  // rejected()
})
console.log(p);

  • 竞争

原型方法

Promise.prototype.then()

  • then方法接收两个参数,一个是成功时的回调函数,一个是失败时的回调函数

    let p = new Promise(function (resolve, reject) {
      // 将状态修改为成功
      resolve("BNTang");
      // 将状态修改为失败
      // reject("BNTang");
    });
    

    指针函数

    p.then(
      (val) => {
        console.log("val = " + val);
      },
      (err) => {
        console.log("err = " + err);
      }
    )
    

    function函数

    p.then(
      function(val){
        console.log("val = " + val);
      },
      function(err){
        console.log("err = " + err);
      }
    )
    

    function函数2

    function success(data) {
      console.log("成功", data);
    }
    
    function error(data) {
      console.log("失败", data);
    }
    
    promise.then(success, error);
    
  • Promise需要有返回值,在PromiseResult中可以查看

  • 如果new Promise中没有回调;则then里的函数不会执行

    let p = new Promise((res,rej)=>{
    })
    
    p.then(val=>{
      console.log(11); // 11不输出
    })
    
  • then获取返回值,成功则进入第一个函数,失败进入第二个函数

    function f() {
      return "ghn"
    }
    
    let p = new Promise((resolved, rejected) => {
      // resolved(f())
      rejected(f())
    })
    
    p.then(
      (val) => {
        console.log("val = " + val);
      },
      (err) => {
        console.log("err = " + err);
      }
    )
    console.log(p)
    

  • then也会返回一个新的Promise对象,这个新Promise的状态取决于回调函数的执行情况,默认是undefined

    let p = new Promise((res, rej) => {
      res(11)
    })
    
    let p1 = p.then(
      (val) => {
        console.log("val1= " + val);
        return { name: 'ghn' }
      }, (err) => {
        console.log("err1 = " + err);
      }
    )
    
    p1.then(value => {
      console.log("p1-then = " + JSON.stringify(value));
    })
    
    console.log(p);
    console.log(p1);
    

  • then中抛出异常或返回失败,第二个thenpromise实例状态是根据p.then的返回值决定的

    let p = new Promise((res, rej) => {
      res(11)
    })
    
    let p1 = p.then(
      (val) => {
        console.log("val1= " + val);
        // return { name: 'ghn' }
        return new Promise((resolved,   rejected) => {
          rejected(2)
        })
        // throw new Error("my error")
      }, (err) => {
        console.log("err1 = " + err);
      }
    )
    
    p1.then((val) => {
      console.log("p1-then = " + JSON.stringify(val));
    },(err) => {
      console.log("p1-then-err = " + JSON.stringify(err));
    })
    console.log(p);
    console.log(p1);
    

Promise.prototype.catch()

  • 基础使用

    p.then(
      (data) => {
        console.log('resolved',data);
      },(err) => {
        console.log('rejected',err);
      }
    ); 
    
    p.then((data) => {
      console.log('resolved',data);
    }).catch((err) => {
      console.log('rejected',err);
    });
    
  • 使用catch捕获异常

    let p = new Promise((res, rej) => {
      res(11)
    })
    
    let p1 = p.then(
      (val) => {
        console.log("val1= " + val);
        // return { name: 'ghn' }
        // return new Promise((resolved, rejected) => {
        //   rejected(2)
        // })
        throw new Error("my error")
      }, (err) => {
        console.log("err1 = " + err);
      }
    ).catch(err => {
      console.log("catch = " + err.message);
      // 根据错误类型判断是否继续抛出
      if (err instanceof Error) {
        // 如果错误是使用 new Error() 创建的,则不再继续传递
        return;
      }
      // 如果错误是其他类型,如Promise的reject方法传递的值,则继续抛出
      throw err;
    })
    
    p1.then((val) => {
      console.log("p1-then = " + JSON.stringify(val));
    },(err) => {
      console.log("p1-then-err = " + JSON.stringify(err));
    })
    console.log(p);
    console.log(p1);
    

静态方法

Promise.all()

Promise.all() 方法是 && 的关系;Promise.any() 方法是 || 的关系; Promise.race()方法是 赛跑机制

var p = Promise.all([p1, p2, p3]);
  • 只有p1、p2、p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数
let p1 =new Promise(function(resolve,reject){
   resolve(1);
});
let p2 = new Promise(function(resolve,reject){
   resolve(2);
});
let p3 = new Promise(function(resolve,reject){
   resolve(3);
});

Promise.all([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
  • 只要p1、p2、p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
let p1 =new Promise(function(resolve,reject){
   resolve(1);
});
let p2 = new Promise(function(resolve,reject){
   resolve(2);
});
let p3 = new Promise(function(resolve,reject){
   reject(3);
});

Promise.all([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
  • Promise.all() 方法提供了并行执行异步操作的能力,在 all 中所有异步操作结束后才执行回调
function p1() {
  var promise1 = new Promise(function (resolve, reject) {
    console.log("p1的第一条输出语句");
    resolve("p1完成");
  });
  return promise1;
}

function p2() {
  var promise2 = new Promise(function (resolve, reject) {
    console.log("p2的第一条输出语句");
    setTimeout(() => {
      console.log("p2的第二条输出语句");
      resolve("p2完成");
    }, 2000);
  });
  return promise2;
}

function p3() {
  var promise3 = new Promise(function (resolve, reject) {
    console.log("p3的第一条输出语句");
    resolve("p3完成");
  });
  return promise3;
}

Promise.all([p1(), p2(), p3()]).then(function (data) {
  console.log(data);
});
  • Promise.all()获得的成功结果的数组里面的数据顺序和接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚
// 在前端开发请求数据的过程中,会遇到发送多个请求并根据请求顺序获取和使用数据的场景
let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒后醒来`)
    }, time)
  })
}
 
let p1 = wake(3000)
let p2 = wake(2000)
 
Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
  console.log(error)
})

Promise.race()

  • Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败
let p1 =new Promise(function(resolve,reject){
   resolve(1);
});
let p2 = new Promise(function(resolve,reject){
   resolve(2);
});
let p3 = new Promise(function(resolve,reject){
   resolve(3);
});

Promise.race([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
  • 使用场景:几个服务器的好几个接口都提供同样的服务,不知道哪个接口更快,可以使用Promise.race
let p1 = new Promise(function(resolve,reject){
  setTimeout(() => {
    resolve(1);
  }, 1000);
});
let p2 = new Promise(function(resolve,reject){
   reject(2);
});
let p3 = new Promise(function(resolve,reject){
   resolve(3);
});

Promise.race([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});

Promise.any()

  • 只要p1p2状态有一个变为fulfilled,该实例的状态为fulfilled
const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});
 
const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "最终完成");
});
 
const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "很快完成");
});
 
Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
},(err) => {
  console.log(err);
}).catch((aggregateError) => {
   console.log("error");
   console.log(aggregateError);
});
// expected output: "很快完成"
  • 如果所有的 Promises 都失败,该实例的状态将失败(rejected),结果值是包含所有失败状态的 AggregateError 的实例的结果集
const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});
 
const pSlow = new Promise((resolve, reject) => {
  setTimeout(reject, 500, "最终失败");
});
 
const pFast = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "很快失败");
});
 
Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
}).catch((aggregateError) => {
   console.log(aggregateError.errors);
});

链式回调

https://segmentfault.com/a/1190000010420744

then回调:then方法提供一个供自定义的回调函数

  1. 若传入非函数,则会忽略当前then方法
  2. 回调函数中会把上一个then中返回的值当做参数值供当前then方法调用
  3. then方法执行完毕后需要返回一个新的值给下一个then调用(没有返回值默认使用undefined)
  4. 每个then只可能使用前一个then的返回值
  • val接收到的是上一个then或者Promise的结果
  • res是被返回并传递给下一个then作为它的参数
let p = new Promise((resolved, rejected) => {
  resolved(1)
})

let p1 = p.then(
  (val) => {
    console.log(val)
    let res = "child";
    return res;
  }
)

p1.then(
  (val) => {
    console.log(val)
  }
)

// 1
// child

具体使用1:then是否是函数

let func = function() {
  return new Promise((resolve, reject) => {
    resolve('返回值');
  });
};

let cb = function() {
  return '新的值';
}
// 有返回值
func().then(function () {
  return cb();
}).then(resp => {
  console.warn(resp);
  console.warn('1 =========<');
});
// 无返回值
func().then(function () {
  cb();
}).then(resp => {
  console.warn(resp);
  console.warn('2 =========<');
});
// cb()执行后返回的并不是一个函数
// 在Promise规范中会自动忽略调当前then
// 会把func中的返回值供下一个then使用
func().then(cb()).then(resp => {
  console.warn(resp);
  console.warn('3 =========<');
});
// 第一个方法在回调内部返回cb执行后的值
// 第四个方法则直接把cb当做回调
func().then(cb).then(resp => {
  console.warn(resp);
  console.warn('4 =========<');
});

具体使用2:reject和catch

  • reject后的东西,一定会进入then中的第二个回调,如果then中没有写第二个回调,则进入catch
  • resolve的东西,一定会进入then的第一个回调,肯定不会进入catch
  • 仅仅返回一个Error对象并不会使Promise变为rejected状态
  • 为了真正拒绝一个Promise,需要throw一个错误或调用reject()函数
new Promise((resolve, reject) => {
  resolve('请求成功了');
})
.then((value) => {
  console.log(value);
  return new Error('错误');
})
.catch(() => {
  console.log('错误'); //未打印,发生穿透
})
.then((value) => {
  console.log(111);
})
.then((value) => {
  console.log(222);
})
  • 除非catch()再次抛出错误,否则链中之后的任何then()块都将按正常顺序执行,因为catch()会把Promise的状态从rejected转变为fulfilled
new Promise((resolve, reject) => {
  resolve('请求成功了');
})
.then((value) => {
  console.log(value);
  throw new Error('错误');
})
.catch(() => {
  console.log('错误');
})
.then((value) => {
  console.log(111);
})
.then((value) => {
  console.log(222);
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931204.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据处理 | Python实现基于DFCP张量分解结合贝叶斯优化的缺失数据填补

数据处理 | Python实现基于DFCP张量分解结合贝叶斯优化的缺失数据填补 目录 数据处理 | Python实现基于DFCP张量分解结合贝叶斯优化的缺失数据填补实践过程基本介绍研究背景程序设计参考资料实践过程 基本介绍 数据处理 | Python实现基于DFCP张量分解结合贝叶斯优化的缺失数据填…

bug复刻,解决方案---在改变div层级关系时,导致传参失败

问题描述&#xff1a; 在优化页面时&#xff0c;为了实现网页顶部遮挡效果&#xff08;内容滚动&#xff0c;顶部导航栏不随着一起滚动&#xff0c;并且覆盖&#xff09;&#xff0c;做法是将内容都放在一个div里面&#xff0c;为这个新的div设置样式&#xff0c;margin-top w…

Android 之 LayoutInflater (布局服务)

本节引言&#xff1a; 本节继续带来的是Android系统服务中的LayoutInflater(布局服务)&#xff0c;说到布局&#xff0c;大家第一时间 可能想起的是写完一个布局的xml&#xff0c;然后调用Activity的setContentView()加载布局&#xff0c;然后把他显示 到屏幕上是吧~其实这个底…

lnmp架构-tomcat session

tomcat session共享 部署 tomcat 在server2 和 server3上进行同样的操作 保存的信息都会在tomcat日志中保存 tomcat 与nginx的整合 在server1上 当并发量开始增大时 就得做负载均衡 解决 当一个tomcat服务器挂掉后 另一个服务器上有第一个服务器上提交的数据问题 在server2…

wx:for的使用和事件传参,解构赋值的应用

在页面的.js文件中创建了一个对象&#xff0c; 并且在页面的view中调用了两种不同的方法将对象中的元素显示出来&#xff01; 第2种代码要加强理解&#xff01;&#xff01;&#xff01; 小程序中的wx:if wx:elif wx:else 其实好像c语言中的 if-elif-else 在页面的.j…

【大数据】图解 Hadoop 生态系统及其组件

图解 Hadoop 生态系统及其组件 1.HDFS2.MapReduce3.YARN4.Hive5.Pig6.Mahout7.HBase8.Zookeeper9.Sqoop10.Flume11.Oozie12.Ambari13.Spark 在了解 Hadoop 生态系统及其组件之前&#xff0c;我们首先了解一下 Hadoop 的三大组件&#xff0c;即 HDFS、MapReduce、YARN&#xff0…

Linux 内核定时器

一、相关知识点 (一)知识点 1、内核定时器分类 1)标准定时器或系统定时器 2)高精度定时器(HRT) 头文件:#include <linux/hrtimer.h> 2、检查系统是否可用HRT 1)查看内核配置文件 CONFIG_HIGH_RES_TIMERS=y 2)查看机器 …

Vue2向Vue3过度Vuex核心概念module模块

目录 1 核心概念 - module1.目标2.问题3.模块定义 - 准备 state 2 获取模块内的state数据1.目标&#xff1a;2.使用模块中的数据3.代码示例 3 获取模块内的getters数据1.目标&#xff1a;2.语法&#xff1a;3.代码演示 4 获取模块内的mutations方法1.目标&#xff1a;2.注意&am…

js实现数据关联查找更新。数据求和验证

为了实现这个功能我们和后端定义了数据结构 data:{id&#xff1a;‘’&#xff0c;formInfo:,formInfo2:,formInfo3:,formInfo4:, ......deailData:[ // 明细数据 // saleData 查询带出的对应明细序列号数据{ id:, ocopyId:, copyId:, odoId:, ......, saleData:[ { id:, oc…

unity-AI自动导航

unity-AI自动导航 给人物导航 一.地形创建 1.首先我们在Hierarchy面板中创建一个地形对象terrian&#xff0c;自行设定地形外貌&#xff0c;此时我们设置一个如下的地形外观。 二.创建导航系统 1.在主人公的Inspector、面板中添加Nav Mesh Agent &#xff08;导航网格代理&…

【Linux】手把手教你实现udp服务器

网络套接字~ 文章目录 前言一、udp服务器的实现总结 前言 上一篇文章中我们讲到了很多的网络名词以及相关知识&#xff0c;下面我们就直接进入udp服务器的实现。 一、udp服务器的实现 首先我们需要创建五个文件(文件名可以自己命名也可以和我一样)&#xff0c;分别是makefile…

Unity3d C#实现调取网络时间限制程序的体验时长的功能

前言 如题的需求应该经常在开发被提到&#xff0c;例如给客户体验3–5天的程序&#xff0c;到期后使其不可使用&#xff0c;或者几年的使用期限。这个功能常常需要使用到usb加密狗来限制&#xff0c;当然这也的话就需要一定的硬件投入。很多临时提供的版本基本是要求软件来实现…

Java如何将jar包上传到Maven中央仓库(超详细2023最新版)

文章目录 Java如何将jar包上传到Maven中央仓库引言Step1&#xff1a;注册 JIRA 账号Step2&#xff1a;发布申请Step3&#xff1a;下载并安装GPGStep4&#xff1a;配置maven的setting.xmlStep5&#xff1a;配置pom.xmlStep6&#xff1a;上传 jar 包Step7&#xff1a;引入 jar 包…

SwiftUI 中限制任意视图为指定的屏幕旋转方向

功能需求 在 SwiftUI 开发中,我们有时需要限制 App 中某些视图为特定的屏幕旋转方向,而另一些视图不做限制(或做其它限制),这可以做到吗? 如上图所示:我们成功的限制了 SwiftUI 中不同视图对应于不同的屏幕旋转方向(Interface Orientations)。 在本篇博文中,您将学到…

OpenCV - C++实战(01) — OpenCV简介

目录 第1章 OpenCV简介 1.1 简介 1.1.1 OpencV 库简介 1.1.2 命名空间 1.2 OpenCV模块 1.3 装载、显示和存储图像 1.3.1 创建图像 1.3.2 读取图像 1.3.3 定义窗口与显示图像 1.3.4 图像翻转 1.3.5 保存图像 1.3.6 图像的复制 1.3.7 创建数组和向量 1.…

01、前端使用 thymeleaf 后,视图页面找不到---Cannot resolve MVC View ‘xxxxx前端页面‘

Cannot resolve MVC View ‘xxxxx前端页面’ 没有找到对应的mvc的前端页面。 代码&#xff1a;前端这里引入了 thymeleaf 模板 解决&#xff1a; 需要添加 thymeleaf 的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…

APP调用bindService的跨进程调用过程

app执行bindService时会经过如下8次跨系统进程调用过程&#xff1a; 第1步&#xff1a;通过AMS.getService跨进程调用 第2步&#xff1a;AMS返回它的IBinder 第3步&#xff1a;通过AMS的IBinder调用AMS的bindService方法 第4步&#xff1a;而AMS存放有Server端的IBinder&…

华为数通方向HCIP-DataCom H12-821题库(单选题:101-120)

第101题 可用于多种路由协议,由 ​​if-match​​​和 ​​apply​​子句组成的路由选择工具是 A、​​route-policy​​ B、​​IP-Prefix​​ C、​​commnityfilter​​ D、​​as-path-filter​​ 答案&#xff1a;A 解析&#xff1a; Route-policy&#xff08;路由策…

扫雷小游戏

目录 一.扫雷小游戏 二.游戏主体一览 ​编辑 三.模块化设计扫雷游戏 3.1打印欢迎菜单 3.2创建两个二维数组 3.3棋盘稍加修改 3.4布置雷 3.5排查雷 四.游戏总体代码 4.1game.h头文件 4.2game.c函数实现源文件 4.3游戏main函数主体 五.游戏效果图 一.扫雷小游戏 这是…

EB Tresos第一个项目报13026

EB项目创建 前期的准备工作见以上这篇文章&#xff0c;不做过多叙述&#xff1b;但是点击Generate Project会报错&#xff0c;报错如下&#xff1a; Code generator finished. Errors “1” Warnings “0” 然后点击 Problems View 查看提示&#xff0c;提示如下&#xff1a; …