这是我参与【第四届青训营】笔记创作活动的第3天。
1.1. Promise 是什么?
1.1.1. 理解
- 抽象表达: 1) Promise 是一门新的技术(ES6 规范) 2) Promise 是 JS 中进行异步编程的新解决方案 备注:旧方案是单纯使用回调函数
- 具体表达:
- 从语法上来说: Promise 是一个构造函数
- 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值
1.1.2. promise 的状态改变
- pending 变为 resolved
- pending 变为 rejected
Promise的状态
实例对象中的一个属性 【PromiseState】
pending 未决定的 resolve / fullfilled 成功 rejected 失败
-
说明: 只有这 2 种, 且一个 promise 对象只能改变一次 无论变为成功还是失败, 都会有一个结果数据 成功的结果数据一般称为 value, 失败的结果数据一般称为 reason
Promise对象的值
实例对象中的另一个属性 【PromiseResult】
保存着异步任务【成功/失败】 的结果
resolve rejected
1.1.3. promise 的基本流程
1.1.4. promise 的基本使用
-
使用 1: 基本编码流程
<script> // 1) 创建 promise 对象(pending 状态), 指定执行器函数 const p = new Promise((resolve, reject) => { // 2) 在执行器函数中启动异步任务 setTimeout(() => { const time = Date.now() // 3) 根据结果做不同处理 // 3.1) 如果成功了, 调用 resolve(), 指定成功的 value, 变为 resolved 状 态 if (time%2===1) { resolve('成功的值 '+ time) } else { // 3.2) 如果失败了, 调用 reject(), 指定失败的 reason, 变为 rejected 状态 reject('失败的值' + time) } }, 2000) }) // 4) 能 promise 指定成功或失败的回调函数来获取成功的 vlaue 或失败的 reason p.then( value => { // 成功的回调函数 onResolved, 得到成功的 vlaue console.log('成功的 value: ', value) }, reason => { // 失败的回调函数 onRejected, 得到失败的 reason console.log('失败的 reason: ', reason) } ) </script> -
使用 2: 使用 promise 封装基于定时器的异步
<script> function doDelay(time) { // 1. 创建 promise 对象 return new Promise((resolve, reject) => { // 2. 启动异步任务 console.log('启动异步任务') setTimeout(() => { console.log('延迟任务开始执行...') const time = Date.now() // 假设: 时间为奇数代表成功, 为偶数代表失败 if (time %2=== 1) { // 成功了 // 3. 1. 如果成功了, 调用 resolve()并传入成功的 value resolve('成功的数据 ' + time) } else { // 失败了 // 3.2. 如果失败了, 调用 reject()并传入失败的 reason reject('失败的数据 ' + time) } }, time) }) } const promise = doDelay(2000) promise.then( value => { console.log('成功的 value: ', value) }, reason => { console.log('失败的 reason: ', reason) }, ) </script>
-
使用 3: 使用 promise 封装 ajax 异步请求
<script> /* 可复用的发 ajax 请求的函数: xhr + promise */ function promiseAjax(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { if (xhr.readyState!==4) return const {status, response} = xhr // 请求成功, 调用 resolve(value) if (status>=200 && status<300) { resolve(JSON.parse(response)) } else { // 请求失败, 调用 reject(reason) reject(new Error('请求失败: status: ' + status)) } } xhr.open("GET", url) xhr.send() }) } promiseAjax('https://api.apiopen.top2/getJoke?page=1&count=2&type=vid eo') .then( data => { console.log('显示成功数据', data) }, error => { alert(error.message) } ) </script>