目录

1.基本使用

2.Promise的串联


1.基本使用

首先清楚promise的过程:事件从unsettled未解决阶段(pending状态)开始发展到settled已解决阶段(resolved和rejected状态),Promise对象可以传resolve与reject两个函数,其中resolve函数将Promise推向resolved阶段,reject函数将Promise推向rejected阶段,且两者均只可传一个参数,表示推向状态的数据,下面给个图理解一下

注册thenable函数:当Promise是resolved状态时,执行thenable函数,注册格式如【例1-1】

注册catchable函数:当Promise是rejected状态时,执行catchable函数,注册格式如【例1-1】

【例1-1】pro.then可以只添加thenable函数,pro.catch可以单独添加catchable函数

方法一

const pro = new Promise((resolve, reject) => {})
pro.then(data => { //data是状态数据})
pro.catch(err => { //err是状态数据})

方法二

const pro = new Promise((resolve, reject) => {})
pro.then(data => {}, err => {})

【注】

1)如果当前是未解决阶段,thenable函数和catchable函数会加入到作业队列,等待状态到达后执行

2)未解决阶段的处理函数是同步的,会立即执行,thenable和catchable函数是异步的,就算是立即执行,也会加入到事件队列中等待执行,并且,加入的是微队列【例1-2】

4)在未解决阶段的处理函数中,如果发生未捕获的错误,会将状态推向rejected,并会被catchable捕获【例1-3】

5)一旦状态推向了已解决阶段,无法再对状态做任何更改

6)Promise并没有消除回调,只是让回调变得可控

【例1-2】

const pro = new Promise((resolve, reject) => {console.log('未解决阶段');setTimeout(() => {console.log('计时器进宏队列')}, 0);resolve(123);
})
pro.then(data => {console.log(data);
})
console.log('执行栈不为空');

【结果】首先事件是pending状态,执行第二行代码,打印“未解决阶段”;之后定时器线程监控到有计时器事件,计时器事件进入宏队列,等待执行,然后状态到达resolved,调用thenable函数,放进微队列,但是由于此时的执行栈并不是空栈,还有log事件,因此先执行第十一行代码,打印“执行栈不为空”,之后执行栈为空,优先执行微队列中的thenable函数,打印data“123”,再执行宏队列,打印“计时器进宏队列”,结果图1-2所示

图1-2

【例1-3】

const pro = new Promise((resolve,reject)=>{throw new Error('rejected');
})
pro.then(data =>{console.log(data);
})
pro.catch(err=>{console.log(err);
})

【结果】

图1-3

2.Promise的串联

当后续的Promise需要用到之前的Promise的处理结果时,需要Promise的串联。在Promise对象中,无论then方法还是catch方法,它们都具有返回值,返回的是一个全新的Promise对象【例2-1】

【注】它的状态满足下列规则

  • 如果当前的Promise是未解决的,得到的新的Promise是挂起状态【例2-2】
  • 后续的Promise一定会等到前面的Promise有了后续处理结果后才会变成已解决状态【例2-2】
  • 如果当前的Promise是已解决的,会运行相应的后续处理函数,并将后续处理函数的结果(返回值)作为resolved的状态数据,应用带新的Promise中,如果后续处理函数发生错误,则把返回值作为rejected状态数据,应用到新的Promise中【例2-3】

【注】若前面的Promise的后续处理,返回的是Promise,则返回的新的Promise状态和后续处理返回的Promise状态保持一致【例2-4】

【例2-1】

// then/catch的返回结果是一个新的Promise
const pro = new Promise((resolve, reject) => {if (Math.random() > 0.5) {resolve(1);} else {reject(2);}
})
const pro1 = pro.then(result => {return result * 2;
}, err => {return err * 2
})
console.log('pro:',pro);
console.log('pro1:',pro1);

【结果】

图2-1

【例2-2】

//当前Promise为解决状态,则新的得到的Promise是挂起状态
const pro = new Promise((resolve, reject) => {setTimeout(() => {resolve(123)}, 500);
})
const pro1 = pro.then(result => {console.log(result);
})
console.log(pro);
console.log(pro1);

【结果】

图2-2-1

等pro的后续处理函数执行以后,pro1的挂起状态变为resolved状态,

图2-2-2

【例2-3】***重点***

const pro = new Promise((resolve, reject) => {
if (Math.random() > 0.5) {//运行pro的thenable函数resolve(1);
} else {//运行pro的catchable函数reject(2);
}
})
const pro1 = pro.then(result => {
//pro的thenable函数
if (Math.random() > 0.5) {console.log('状况1')//执行pro1的thenable函数,且状态数据来自pro的thenable函数,打印 1 * 2 * 2 = 4return result * 2;
} else {console.log('状况2')//执行pro1的catchable函数,且状态数据来自pro的thenable函数,打印 1 * 3 * 3 = 9throw result * 3;
}
}, err => {
//pro的catchable的函数
if (Math.random() > 0.5) {console.log('状况3')//执行pro1的thenable函数,且状态数据来自pro1的catchable函数,打印 2*2*2 = 8return err * 2;
} else {console.log('状况4')//执行pro1的catchable函数,且状态数据来自pro1的catchable函数,打印 2 * 3 * 3 = 18throw err * 3
}
})
//前者为pro1的thenable函数,后者为pro1的catchable函数
pro1.then(result => console.log(result * 2), err => console.log(err * 3))

【结果】上述4种状态,分别打印4,9,8,18,感觉代码分析的很清楚了,这里就不贴图了,小伙伴可以自己试试

【例2-4】

const pro1 = new Promise((resolve, reject) => {resolve(1);
})
const pro2 = new Promise((resolve, reject) => {setTimeout(() => {resolve(2)}, 2000);
})
pro1.then(result => {console.log('结果出来了,得到的是一个Promise');return pro2;
}).then(result => {console.log(result);
}).then(result => {console.log(result);
})

【结果】第一行立即打印,第二行和第三行隔2000毫秒打印,并且数据和状态是拿pro2的状态和数据,第3行打印undefined,是因为前一个Promise没有返回值

图2-4

Promise第一篇:基本使用方法和串联相关推荐

  1. 普元EOS开发积累第一篇(常见错误解决方法) 持续更新

    普元EOS开发积累第一篇(常见错误解决方法) 持续更新 参考文章: (1)普元EOS开发积累第一篇(常见错误解决方法) 持续更新 (2)https://www.cnblogs.com/tangjing ...

  2. Webpack系列-第一篇基础杂记

    系列文章 Webpack系列-第一篇基础杂记 Webpack系列-第二篇插件机制杂记 Webpack系列-第三篇流程杂记 前言 公司的前端项目基本都是用Webpack来做工程化的,而Webpack虽然 ...

  3. Electron系列教程——第一篇:入门

    Electron系列教程--第一篇:入门 一.楔子 想要学习Electron,跟着官网或者中文网,仔细阅读,并实践,其实是够了,不必要重复.那为什么还要写这个系列呢?大概有两方面原因,其一:我使用el ...

  4. 微信小程序商城项目实战(第一篇:项目搭建与首页)

    商城项目第一篇 项目搭建 项目结构 编写整个项目中需要用到的功能 request.js 全局样式 组件(搜索框) 首页 代码编写 效果图 项目搭建 后端接口:https://www.showdoc.c ...

  5. 属于窄带噪声的是热噪声_时钟201系列: 非相位噪声的情况 (第一篇)

    欢迎来到Silicon Labs(亦称"芯科科技")的新系列博客文章"时钟201"的第一篇内容-非相位噪声的情况-第一部分.我们之前的系列博文"时钟1 ...

  6. 研究生第一篇科研论文常犯问题总结

    ↑ 点击蓝字 关注视学算法 作者丨喻海良,中南大学教授,博士生导师 来源|http://blog.sciencenet.cn/blog-117889-1018759.html 极市导读 本文作者为中南 ...

  7. Spotify敏捷模式详解三部曲第一篇:研发团队

    本文转自:Scrum中文网 引言 2018年4月,来自北欧瑞典的音乐流媒体公司.百亿美元独角兽Spotify创造了历史,它成为了当代上市公司当中,第一家通过"直接上市"的方式在美国 ...

  8. 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

    作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...

  9. RabbitMQ学习总结 第一篇:理论篇

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

最新文章

  1. nginx长连接出现504的解决办法
  2. pyplot输出的绘图界面中文乱码的解决方案
  3. 538B. Quasi Binary
  4. python垃圾回收机制为什么标记能解决循环引用问题_python 关于循环引用以及标记清除的问题...
  5. android 录屏工具,安卓手机上最好的录屏软件在这里
  6. 推荐6款好用、免费的远程控制软件【远程管理工具】
  7. gtj2018如何生成工程量报表_工程量清单计价规范2018
  8. 自然语言处理之语言模型(LM)
  9. 【C++】跟着老九君学习记录(一)
  10. matlab中complex的详细用法,Matlab基本函数-complex函数
  11. 用好这 28 个工具,开发效率爆涨|云效工程师指北
  12. 拼多多改销量10+是怎么回事
  13. linux ssl证书卸载,linux下nginx怎么卸载ssl证书
  14. ClasssLoader
  15. 许一世情 陪你 浪尽天涯
  16. 为什么ctrl+shift+方向键不管用了_为什么你的祛痘产品不管用?
  17. 【附源码】Python计算机毕业设计网络求职招聘系统
  18. 【QMT策略编写】如何优雅地调教QMT量化平台编写量化策略(使用notepad++、pycharm、vscode等外部IDE编写量化交易代码)
  19. Cesium开发:关于加载CGCS2000切片
  20. Pr 入门系列之四:编辑(基础篇)

热门文章

  1. Log4j执行漏洞修复教程
  2. 分布式系统概念 | 分布式理论:CAP、BASE
  3. 趣谈设计模式 | 代理模式(Proxy):利用代理来控制对象的访问
  4. 第30讲:如何爬app的数据
  5. Python 中的 os 模块常见方法
  6. 为什么 Go 模块在下游服务抖动恢复后,CPU 占用无法恢复
  7. 模拟实现mapset
  8. 区间调度之区间合并问题
  9. Cisco WebEx:企业协作服务中的音频需求
  10. 直播预告│据说这是人工智能领域里最难的一门学问……