当前位置: 首页 > news >正文

【前端】ES6:Promise对象和Generator函数

文章目录

  • 1 Promise对象
    • 1.1 回调地狱
    • 1.2 Promise使用
    • 1.3 Promise对象的状态
    • 1.4 Promise.all
    • 1.5 Promise.race
  • 2 Generator函数
    • 2.1 基本语法
    • 2.2 异步流程
      • 2.2.1 手动版本
      • 2.2.2 自动版本

1 Promise对象

Promise是异步编程的一种解决方案,比传统的解决方案回调函数,更合理和更强大。

ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象 。

  • 指定回调函数方式更灵活易懂。
  • 解决异步 回调地狱 的问题。

1.1 回调地狱

当一个回调函数嵌套一个回调函数的时候,就会出现一个嵌套结构,当嵌套的多了就会出现回调地狱的情况。

比如我们发送三个ajax请求:

  • 第一个正常发送。
  • 第二个请求需要第一个请求的结果中的某一个值作为参数。
  • 第三个请求需要第二个请求的结果中的某一个值作为参数。

回调地狱,其实就是回调函数嵌套过多导致的。

ajax({url: '我是第一个请求',success (res) {// 现在发送第二个请求ajax({url: '我是第二个请求'data: { a: res.a, b: res.b },success (res2) {// 进行第三个请求ajax({url: '我是第三个请求',data: { a: res2.a, b: res2.b },success (res3) { console.log(res3) }})}})}
})

1.2 Promise使用

new Promise(function (resolve, reject) {// resolve 表示成功的回调// reject 表示失败的回调
}).then(function (res) {// 成功的函数
}).catch(function (err) {// 失败的函数
})

1.3 Promise对象的状态

Promise 对象通过自身的状态,来控制异步操作。

Promise 实例具有三种状态。

  • 异步操作未完成(pending)
  • 异步操作成功(fulfilled)
  • 异步操作失败(rejected)

这三种的状态的变化途径只有两种。

  • 从“未完成”到“成功”
  • 从“未完成”到“失败”

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是Promise这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise实例的状态变化只可能发生一次。

因此,Promise的最终结果只有两种。

  • 异步操作成功,Promise实例传回一个值(value),状态变为fulfilled。
  • 异步操作失败,Promise实例抛出一个错误(error),状态变为rejected。

1.4 Promise.all

Promise.all()方法用于将多个Promise实例,包装成一个新的Promise实例。

const p = Promise.all([p1, p2, p3]);

p的状态由p1,p2,p3 决定,分成两种情况。

  • 只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。
  • 只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

1.5 Promise.race

Promise.race()方法同样是将多个Promise实例,包装成一个新的Promise实例。

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数。

2 Generator函数

Generator函数是ES6提供的一种异步编程解决方案。

Generator函数是一个状态机,封装了多个内部状态。

执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。

2.1 基本语法

function *gen(){console.log(1)yield;console.log(2)yield;console.log(3)
}let g = gen()
g.next()
g.next()
g.next()

yield(产出)表达式是暂停执行的标记,而next方法可以恢复执行。

function *gen(){yield  1;yield  2;
}let g = gen()
let res1 = g.next()
console.log(res1)
let res2 = g.next()
console.log(res2)
let res3 = g.next()
console.log(res3)
function *gen(){let res1 = yield;console.log(res1)let res2 = yield;console.log(res2)
}let g = gen()
g.next("data-1")
g.next("data-2")
g.next("data-3")
function *gen(){let res1 = yield "aaa"//产出console.log("gen内部",res1)let res2 = yield "bbb"console.log("gen内部",res2)
}let g = gen()
let res1 = g.next("传入-11111") // 第1次next(),到yield停,"aaa"赋值给res1
console.log(res1)               // 打印:aaa
let res2 = g.next("传入-22222") // 第2次next(),将"传入-22222"赋值给let res1 = yield "aaa"中的res1,打印:gen内部,传入-22222,到yield停,"bbb"赋值给res2
console.log(res2)               // 打印:bbb
let res3 = g.next("传入-33333") // 将"传入-33333"赋值给let res2 = yield "bbb"中的res2,打印:gen内部,传入-33333
console.log(res3)               // 打印:undefined

2.2 异步流程

2.2.1 手动版本

function *gen(){let res1 = yield ajax("1.json")console.log(res1)let res2 = yield ajax("2.json")console.log(res2)
}let g = gen()   g.next().value.then(data=>{g.next(data).value.then(data=>{g.next(data)})
}) //async await 内置自动执行器

2.2.2 自动版本

function* gen() {let res1 = yield ajax("1.json")console.log(res1)let res2 = yield ajax("2.json")console.log(res2)
}function AutoRun(gen) {let g = gen();function next(data) {let res = g.next(data); // 第1次next()if(res.done) return res.value.then(function (data) {next(data); // 第2次next()});}next();
}AutoRun(gen);

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深度学习自编码器 - 自编码器的应用篇
  • 木舟0基础学习Java的第二十九天(Spring,Spring的属性注入(xml,注解))
  • 编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MinGW版)
  • leetcode第十四题:最长公共前缀
  • CTC loss 博客转载
  • 鸿蒙【项目打包】- .hap 和 .app;(测试如何安装发的hap包)(应用上架流程)
  • 【机器学习】--- 自然语言推理(NLI)
  • 巨人网络参展云栖大会,两款“游戏+AI”自研大模型应用首发
  • docker之自定义镜像上传至阿里云
  • 山体滑坡检测系统源码分享
  • 力扣(leetcode)每日一题 2374 边积分最高的节点
  • Godot游戏如何提升触感体验
  • 大佬,简单解释下“嵌入式软件开发”和“嵌入式硬件开发”的区别
  • Mistral AI 又又又开源了闭源企业级模型——Mistral-Small-Instruct-2409
  • 【图像压缩与重构】基于标准+改进BP神经网络
  • [PHP内核探索]PHP中的哈希表
  • $translatePartialLoader加载失败及解决方式
  • 11111111
  • 2017前端实习生面试总结
  • CentOS7 安装JDK
  • Java的Interrupt与线程中断
  • MaxCompute访问TableStore(OTS) 数据
  • MD5加密原理解析及OC版原理实现
  • Otto开发初探——微服务依赖管理新利器
  • php面试题 汇集2
  • redis学习笔记(三):列表、集合、有序集合
  • spring security oauth2 password授权模式
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 给github项目添加CI badge
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 使用Swoole加速Laravel(正式环境中)
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 小程序button引导用户授权
  • 移动端 h5开发相关内容总结(三)
  • 《天龙八部3D》Unity技术方案揭秘
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (LeetCode 49)Anagrams
  • (不用互三)AI绘画工具应该如何选择
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • . NET自动找可写目录
  • .htaccess配置重写url引擎
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .Net 垃圾回收机制原理(二)
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/C#⾯试题汇总系列:⾯向对象
  • .NET6实现破解Modbus poll点表配置文件
  • .NetCore发布到IIS
  • .net反编译的九款神器
  • .Net下的签名与混淆
  • .NET与 java通用的3DES加密解密方法
  • .net中应用SQL缓存(实例使用)