初体验
//promise当中包裹一个异步
//
const p =new Promise((resolve,reject)=>{
setTimeout(()=>{
if(){
//成功调用resolve,且可以将promise对象的状态设置为成功
resolve(可以传递参数)
}else{
//成功调用reject,且可以将promise对象的状态设置为失败
reject(可以传递参数)
}
},1000)
})
p.then((value)=>{
//成功的回调
},(reason)=>{
//失败的回调
})
Promise封装ajax请求
const p=new Promise((resolve,reject)=>{
const xhr=new XMLHttpResquest()
xhr.open('get','')
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<300){
//成功请求
resolve()
}else{
//输出失败状态码
reject()
}
}
}
}).then(()=>{
//成功的回调
},()=>{
//失败的回调
})
回顾await和axios
await 原生
const fun=async function(){
await new Promise((resolve,reject)=>{
const xhr=new XMLHttpResquest()
xhr.open('get','')
xhr.send()
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status>=200&&xhr.status<300){
//成功请求
resolve()
}else{
//输出失败状态码
reject()
}
}
}
}).then(()=>{
//成功的回调
},()=>{
//失败的回调
})
}
await能够接收promise对象,await本身是异步的,是一种处理异步任务的机制,在函数当中能够使一个整体函数变成同步,从上到下一次执行代码
//vue当中常写
封装:
import axios from "axios";
// //请求地址
let baseUrl = '/api'
Vue.prototype.$baseUrl = 'http://com.cn'
axios.defaults.baseURL = baseUrl
Vue.prototype.$http = (url, method, data, async, fun) => {
axios({
url: url,
method: method,
data: JSON.stringify(data),
async: async
}).then(resp => {
fun(resp.data)
}).catch(err => {
console.log(err)
})
}
使用:
async fun(){
let res=await this.$http('','').catch((err))
}
promise
状态--PromiseState
pending变为resolved/rejected,只有这两种状态,且promise只能改变一次,都只会有一个结果数据,成功的一般称为value,失败的为reason
值--PromiseResult
保存成功失败的结果,只有reject和resolve可以修改
promise基本流程
promise方法
Promise.all
如果所有都是成功状态就返回成功,若有失败就返回失败
成功:
失败:
let p1=new Promise((resolve,reject)=>{
resolve('ok')
})
let p2=Promise.resolve('')
const result=Promise.all([p1,p2])
Promise.race
第一返回的promise对象的状态决定,成功race就返回成功,反之
promise当中的关键问题
- 可以为一个promise指定多个then,当状态发生改变的时候都会被调用
- 改变promise状态和指定回调函数谁先谁后,都有可能
let p =new Promise((resolve,reject)=>{
resolve(ok)//改变状态,这个先?
})
//这个先?
p.then(value=>{
},reason)
//状态先改变的情况:就是执行器当中是一个同步任务的时候
let p =new Promise((resolve,reject)=>{
resolve(ok)这个先
})
p.then(value=>{
},reason)
//回调函数先的情况:就是执行器当中是一个异步任务的时候
let p =new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(ok)
},1000)
})
这个先
p.then(value=>{
},reason)
-
只有状态改变之后才能拿到数据
-
链式调用
//在p成功之后又继续执行promise,如果这个promise成功,则p.then返回成功
let p =new Promise((resolve,reject)=>{
resolve(ok)这个先
})
p.then(value=>{
return new Promise((resolve,reject)=>{
})
},reason)
- 异常穿透(只在最后指定catch)
let p =new Promise((resolve,reject)=>{
resolve(ok)
})
//可以直接输出11,22,33,
p.then(value=>{
//throw '失败' //不用在下一个then里面指定reject,他会跳到catch直接catch异常
console.log('111')
}).then(value=>{
console.log('222')
}).then(value=>{
console.log('333')
}).catch(reason=>{
console.warn(reason)
})
promise与事件循环
事件循环(在我的另外一篇文章当中有详细说明捏小红书一面凉经(二) - 掘金 (juejin.cn))简单来说就是代码执行大致分为同步和异步,同步代码放入执行栈立即执行,而异步代码会放入宿主环境种,待异步代码等待结束之后会放入任务队列,当执行栈当中的代码都执行完成之后,会到任务队列当中去寻找是否有排队的代码,有就执行,执行完成之后又会到任务队列当中询问,这样不断询问的过程就叫做事件循环
而异步当中又会分为宏任务和微任务,宏任务是指由宿主环境发起的比如定时器,而微任务是由js引擎发起的任务,比如script、promise
而我们要注意promise本身是同步的,是他的回调函数.catch、.then是异步的