Promise教程(一)
第1章:准备
区别实例对象与函数对象
- 实例对象:new函数产生的对象,称为实例对象,简称为对象
- 函数对象:将函数作为对象使用时,简称为函数对象
同步回调
- 理解:立即执行,完全执行完了才会结束,不会放入回调队列中
- 例子:数组遍历相关的回调函数、Promise的excutor函数
异步回调
- 理解:不会立即执行,会放入回调队列中将来执行
- 例子:定时器回调、ajax回调、Promise的成功/失败回调
进一步理解js中的错误(ERROR)和错误处理
-
错误的类型
-
Error:所有错误的父类型
-
ReferenceError:引用的变量不存在
console.log(a)
-
TypeError:数据类型不正确
const demo = ()=>{}
demo()()
-
RangeError:数据值不在其所允许的范围内
const demo() = ()=>{demo()}
demo()
-
SyntaxError:语法错误
console.log(
-
-
错误处理
-
捕获错误:try{}catch{}
try中放可能出现错误的代码,一旦出现错误立即停止try中代码的执行,调用catch,并携带错误信息
-
抛出错误:throw error
-
-
错误对象
- message属性:错误相关信息
- stack属性:记录信息
第2章:Promise的理解和使用
Promise是什么
-
抽象表达:
-
Promise是一门新的技术(ES6提出的)
-
Promise是JS中异步编程的新方案(旧方案是谁?—纯回调)
-
-
具体表达:
- 从语法上来说:Promise是一个内置构造函数,是程序员自己new调用的
- 从功能上来说:Promise的实例对象可以用来封装一个异步操作,并可以获得其成功/失败的值
-
new Promise的时候,要传入一个回调函数,它是同步的回调,会在主线程上执行,它被称为executor函数、
-
每一个Promise实例都有3种状态,分别为:初始化(pending)、成功(fulfilled)、失败(rejected)
-
每一个Promise实例在刚被new出来的那一刻,状态都是初始化(pending)
-
executor函数会接收2个参数,它们都是函数,分别用形参:resolve、reject接收
- 调用resolve,会让Promise实例状态变为:成功(fulfilled),同时可以指定成功的value
- 调用reject,会让Promise实例状态变为:失败(rejected),同时可以指定失败的reason
const promise1 = new Promise((resolve, reject) => { resolve('foo'); }); console.log(promise1);
Promise基本使用
-
重要语法
- new Promise(executor)构造函数
- Promise.prototype.then方法
-
基本编码流程
-
创建Promise的实例对象(pending状态),传入executor函数
-
在executor中启动异步任务(定时器、ajax请求)
-
根据异步任务的结果,做不同的处理:
- 如果异步任务成功了:我们调用resolve(value),让Promise实例对象状态变为成功(fulfilled),同时指定成功的回调
- 如果异步任务失败了:我们调用reject(reason),让Promise实例对象状态变为(rejected),同时指定失败的回调
-
通过then方法为Promise指定成功、失败的回调函数,来获取成功的value、失败的reason
注意:then方法所指定的:成功的回调、失败的回调,都是异步的回调
-
-
关于状态的注意点:
-
三个状态:
- pending:未确定的--------初始状态
- fulfilled:成功的--------调用resolve()后的状态
- rejected:失败的---------调用reject()后的状态
-
两种状态的改变
pending ===> fulfilled
pending ===> rejected
-
状态只能改变一次
-
一个Promise指定多个成功/失败回调函数,都会调用吗?
会。
-
配合ajax使用
//创建一个Promise实例
const p = new Promise((resolve,reject) => {
//创建一个XMLHttpRequest实例
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = () => {
if(xhr.readyState === 4){
if(xhr.status === 200){
//请求成功
resolve(xhr.response)
}else{
//请求失败
reject('出错了')
}
}
}
//配置请求的方式、地址、参数
xhr.open('GET','https://www.tianqiapi.com/free/day?appid=23035354&appsecret=8YvlPNrz')
//配置返回的数据类型为json
xhr.responseType = 'json'
//发送请求
xhr.send()
})
p.then(
(value) => {console.log(value)},//成功的回调
(reason) => {console.log(reason)}//失败的回调
)
封装ajax请求
function sendAjax(url,data){
return new Promise((resolve,reject) => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
resolve(xhr.response)
}else reject('出错了')
}
}
let str = ''
for (let key in data) {
str += `${key}=${data[key]}&`
}
str.slice(0,-1)
xhr.open('GET',url+'?'+str)
xhr.responseType = 'json'
xhr.send()
})
}
const p = sendAjax('https://www.tianqiapi.com/free/day',{appid:23035354,appsecret:'8YvlPNrz'})
p.then(
(value) => {console.log(value)},
(reason) => {console.log(reason)}
)
纯回调封装ajax请求
function sendAjax(url,data,success,error){
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if(xhr.readyState ===4){
if(xhr.status >= 200 && xhr.status < 300){
success(xhr.response)
}else error('出错了')
}
}
let str = ''
for (let key in data) {
str += `${key}=${data[key]}&`
}
str.slice(0,-1)
xhr.open('GET',url+'?'+str)
xhr.responseType = 'json'
xhr.send()
}
sendAjax(
'https://www.tianqiapi.com/free/day',
{appid:23035354,appsecret:'8YvlPNrz'},
(value) => {console.log(value)},//成功的回调
(reason) => {console.log(reason)}//失败的回调
)
几个常用的API
- Promise构造函数:new Promise (executor) {}
- executor函数:是同步执行的,(resolve,reject) => {}
- resolve函数:调用resolve将Promise实例内部状态改为成功(fulfilled)
- reject函数:调用reject将Promise内部立即同步调用,异步代码放在executor函数中
- Promise.prototype.then方法:Promise实例.then(onFulfilled,onRejected)
- onFulfilled:成功的回调函数(value) => {}
- onRejected:失败的回调函数(reason) => {}
- 特别注意(难点):then方法会返回一个新的Promise实例对象
- Promise.prototype.catch方法:Promise实例.catch(onRejected)
- onRejected:失败的回调函数(reason)=> {}
- 说明:catch方法是then方法的语法糖,相当于:then(undefined,onRejected)
- Promise.resolve方法:Promise.resolve(value)
- 说明:用于快速返回一个状态为fulfilled或rejected的Promise实例对象
- 备注:value的值可能是:(1)非Promise值 (2)Promise值
- Promise.reject方法:Promise.reject方法(reason)
- 说明:用于快速返回一个状态必为rejected的Promise实例对象
- Promise.all方法:Promise.all(promiseArr)
- promiseArr:包含n个Promise实例的数组
- 说明:返回一个新的Promise实例,只有所有的promise都成功了才成功,只要有一个失败了就直接失败
- Promise.race方法:Promise.race(promiseArr)
- promiseArr:包含n个Promise实例的数组
- 说明:返回一个新的Promise实例,成功还是失败,以最先出结果的promise为准
如何改变一个Promise实例的状态?
- 执行resolve(value):如果当前是pending就会变为fulfiled
- 执行reject(reason):如果当前是pending就会变为rejected
- 执行器函数(executor)抛出异常:如果当前是pending就会变为rejected
改变Promise实例的状态和指定回调函数谁先谁后?
-
都有可能,正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
-
如何先改变状态再指定回调?
延迟一会再调用then()
-
Promise实例什么时候才能得到数据?
如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据