文章目录
说说你对Promise的相关理解?? 或者 说说promsie到底是个啥东东??
思路:从两个层面进行解答:抽象表达和具体表达
- 抽象表达:promise是JS中进行异步编程的新的解决方案(旧的方案指得是纯回调的形式,即纯指得是没有promise都是回调函数)
- 具体表达:
(1)、从语法来讲promise是一个构造函数
(2)、从功能上来说promise对象可以封装一个异步操作,并可以获得其结果
为什么要用Promise??
1、指定回调函数的方式更加灵活
旧方案:纯回调的方式处理异步任务时:必须在开始启动异步任务之前就将回调函数指定好(如果是先启动异步任务,接着在指定回调,此时的回调已经得不到数据,因为异步任务已经完成了)
新方案:使用promise处理异步任务:启动异步任务 =》返回promise对象 =》给promise对象绑定回调函数(一般是在启动异步任务之后指定回调甚至可以在执行异步任务完成之后进行指定)
2、支持链式调用,可以解决回调地狱的问题
什么是回调地狱??
回调地狱涉及到多个异步操作而且它们是连续串联执行的
什么是连续串联执行??
假如涉及到三个异步操作分别有三个回调函数进行处理,即第二个回调函数执行的条件是第一个回调函数执行的结果,第三个回调函数执行的条件是第二个回调函数执行的结果
回调地狱的缺点??
编码上:不便于阅读
处理异常上:不便于异常的处理(回调函数嵌套中对于异常的处理是进行分别处理的,不便于代码维护)
回调地狱详情请点击
promise是如何解决回调地狱的??
编码上: promise的链式调用,避免了回调函数之间的嵌套
处理异常上:promise的异常传透,使得可以统一用catch对异常进行处理
解决回调地狱的终极方案??
由于promise处理多个异步任务时仍然存在着回调函数,因此使用
async/await
解决回调地狱是最终方案
Promise的用法
Promise构造函数接收一个函数作为参数(执行器函数),该函数的两个参数分别是resolve和reject分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。(它们是两个函数,又JavaScript引擎提供,不是自己部署)
resolve函数的作用,将Promise对象的状态从“未完成”变成“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise的缺点??
- 一旦执行,无法中途取消
一旦新建Promise对象,便开始执行,无法中途取消
2.promise的内部如何执行,检测起来很难
如果当前是处于pending状态,无法得知目前异步任务进展到哪一个阶段,是刚开始执行,还是即将结束
- promise的错误无法在外部被捕捉到,只能在内部进行预判断处理
如果不设置回调函数,Promise内部抛出的错误,不会反映到外部
async和await
async函数
返回值:promise对象
- async函数返回值是promise对象
- promise对象的结果由async函数的返回值决定
await表达式
返回的值:promise成功值、其他值
- await右边的表达式一般为promise对象,也可以是任何要等待的值
(1)、如果表达式右边是promise对象,得到的结果就是promise对象的成功值
(2)、如果表示右边不是promise对象,得到的结果就是它本身
注意:
如果await右边是失败的promise对象,则会抛出异常,
因此可以使用try{await 失败的promise对象}catch(e){‘失败promise的reason’}
注意:
2. await必须写在async函数中,但是async函数中可以没有await表达式
手写promise和ajax的结合
function promiseGet (url) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.responseText,this)
} else {
let resJson = {
code: this.status,
response: this.response
}
reject(resJson, this)
}
}
}
})
}
复制代码