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

Promise查漏及回调地狱结构优化

目录

  • 前言
  • 一、执行器函数的执行顺序
  • 二、如何在then()中抛出错误
  • 三、期约的"非重入"特性
  • 四、串行化期约
  • 五、应对回调地狱
  • 结语

前言

依据《JavaScript高级程序设计》对Promise期约相关进行查缺补漏.


一、执行器函数的执行顺序

执行器函数虽作为期约的参数, 却是期约的初始化程序在同步队列中执行, 即程序从上到下执行下来碰到期约, 会先在同步任务队列执行完执行器函数再进去期约.

ECMAScript暴露的异步结构中, 任何对象都有then方法, 而有实现了该方法的结构即被认为实现了thenable接口. Promise的原型上也实现了then()方法:

new Promise((resolve, reject) => {
...
}).then();

then()只接受函数类型参数且最多2个.


二、如何在then()中抛出错误

then(()=>{throw 'baz';
}); 	
then(()=>{Error('qux');
}) 

两种都正确,前者抛出报错;
后者返回一个包装于Promise对象中的错误对象可以反应调用栈情况, 以正常值输出.


三、期约的"非重入"特性

期约"落定"后, 处理程序(即then的参数函数onResolvedonRejected)仅会加入排期而非立即执行, 而排在处理程序后的同步语句会先执行, 此特性是由Javascript运行时保证的,即then内部语句的输出会晚于then外部更加靠后的语句的输出.
其原因为在一个落定期约上调用then虽会把then中的处理程序推进消息队列, 但在当前线程上的同步代码执行完成前处理程序依然不会被执行. 更符合常理一些的写法, 对一个已写入处理程序的期约落定后, 也会是这样的输出顺序.


四、串行化期约

期约连锁: then()内再构建期约, 串行化异步任务即:

new Promise((resolve, reject) => { console.log ('P1 executor'); setTimeout (resolve, 1000);
})
.then (() => { new Promise((resolve, reject) => { console.log('P2 executor'); setTimeout(resolve, 1000);
})
.then(() => {new Promise((resolve, reject) => { console.log('P3 executor'); setTimeout(resolve, 1000);
});

但书中似乎认为这种串行式结构并未解决回调地狱(未明确表明).


五、应对回调地狱

可见第四节这种串行结构有同质部分,如果将同质部分使用工厂函数调用生产,这种结构可以演化为:

function delayedResolve(str) {return new Promise((resolve, reject) => { console.log(str);setTimeout (resolve, 1000);});
}  //工厂函数delayResolve('P1 executor').then(() => { delayResolve('P2 executor');
})
.then(()=> {delayResolve('P3 executor')
})

每次调用"生产"返回一块期约对象同质部分,返回后相当于回到了期约串行结构:

new Promise().then(() => {delayResolve();
}).then()

上例期约体同质部分只分为一种,打比方如果上例有一段串行块的期约内还输出了1,这就是另一种同质部分,就要再单独为这段输出了1的期约构建工厂函数.

以上为基础,如果不使用期约,以回调函数形式唤起后续的异步操作就会是这样:

function delayedExecute(str, callback = null) { setTimeout(() => { callback && callback();}, 1000)
}delayedExecute('P1callback', () => {delayedExecute('P2callback', () => {delayedExecute('P3callback', () => { delayedExecute('P4callback');});});
});

《JavaScript高级程序设计》中称这样的一种结构, 破除了回调地狱.

那么这种结构到实战中,加上ajax请求就不能再每次传一个字面量,因为我们要模仿回调地狱里下个参数为上个结果的情况,就要把上次请求的结果传到下个回调函数内:

function delayedExecute(params, callback = null) { $.ajax({url: 'xx/xx',type:'post',data: { a: params.a, b: params.b },success (res) { callback && callback(res);}
})
}delayedExecute(data0, (res0) => {delayedExecute(res0, (res1) => {delayedExecute(res1, (res2) => { delayedExecute(res2);});});
});

结语

如有疏漏,请为我指正,谢谢.

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 嵌入式AI---如何用C++实现YOLO的NMS(非极大值抑制)算法
  • 【Kubernetes】常见面试题汇总(十三)
  • 5.1 溪降技术:个人装备
  • 04_Python数据类型_列表
  • 【运维监控】Prometheus+grafana+kafka_exporter监控kafka运行情况
  • linux 操作系统下的cut命令介绍和使用案例
  • JVM字节码
  • UVA1395 Slim Span(最小生成树)
  • Unity3d 以鼠标位置点为中心缩放视角(正交模式下)
  • 详解c++多态---上
  • 动态规划---不相交的线
  • 【前端】ref引用的作用
  • Golang、Python、C语言、Java的圆桌会议
  • Vue.js 计算属性
  • 数据结构:堆的算法
  • download使用浅析
  • fetch 从初识到应用
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • iOS 系统授权开发
  • Python - 闭包Closure
  • Python十分钟制作属于你自己的个性logo
  • vue:响应原理
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 翻译:Hystrix - How To Use
  • 基于axios的vue插件,让http请求更简单
  • 基于遗传算法的优化问题求解
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前端相关框架总和
  • 前端自动化解决方案
  • 思考 CSS 架构
  • 一个SAP顾问在美国的这些年
  • 优秀架构师必须掌握的架构思维
  • 怎么把视频里的音乐提取出来
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • # Redis 入门到精通(九)-- 主从复制(1)
  • # 利刃出鞘_Tomcat 核心原理解析(二)
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (JS基础)String 类型
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (过滤器)Filter和(监听器)listener
  • (九)One-Wire总线-DS18B20
  • (四)库存超卖案例实战——优化redis分布式锁
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转载)深入super,看Python如何解决钻石继承难题
  • ./configure,make,make install的作用
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .Net Winform开发笔记(一)
  • .NetCore项目nginx发布
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET开源快速、强大、免费的电子表格组件