Promise的正常用法
function xx(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resovle('成功的输出')
reject('失败输出')
},3000)
})
}
xx().then(fn1,s1).then(fn2,s2)//fn表示成功调用,s表示失败调用
Promise的API
- Promise.resolve() 制造一个成功或失败
- Promise.reject() 制造一个失败
- Promise.all(数组) 等待全部成功,或者有一个失败
- Promise.race(数组) 等待第一个状态改变
- Promise.allSettled(数组) 等待全部状态改变,API较新,浏览器支持的少
Promise的语法糖
Promise.then(fn1).catch(s1) 等于 Promise.then(fn1,s1)
Promise的面试题
页面有两个按钮 A和B,以及一个输入框,A按钮点击后发送一个请求,返回一个字符串A,B也发请求,但返回字符串B,返回后会把字符串赋值给输入框,但是A,B发送的两个请求返回的时间不同,点击两个按钮的顺序也不一定,B要比A先返回,而最终效果要求是输入框字符的顺序是AB。
primise.all()不好满足这个需求。这需要用一个数组来记录他们,当B请求回来时去数组中对比,顺序不为1,然后再等待,等到A请求回来后,输出A然后再输出B即可。
直接看实现的代码吧:
<body>
<button id="b1">A</button>
<button id="b2">B</button>
<input id="input1" type="text">
</body>
let ajax1 = ()=>{
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(1111)
},5000)
})
}
let ajax2 = ()=>{
return new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(2222)
},3000)
})
}
let batai = []
let duiwu = []
let hi = () =>{
let lastN = batai[batai.length - 1][0]
let lastS = batai[batai.length - 1][1]
console.log(duiwu,'队伍')
console.log(batai,'吧台')
if(duiwu[0][0] === lastN) {
duiwu[0][1](lastS)
duiwu.shift()
batai.pop()
hi()
}
}
b1.onclick = ()=>{
const n = 1
ajax1().then(res=>{
batai.push([n, res])
hi()
})
duiwu.push([n, s=>{
input1.value = s
}])
}
b2.onclick = ()=>{
const n = 2
ajax2().then(res=>{
batai.push([n, res])
hi()
})
duiwu.push([n, s=>{
input1.value = s
}])
}
async await的基本用法
const fn = async ()=>{
const fn1 = await newPromise()
return fn1 + 1
}
相比较Promise,完全没有锁进,就像在写同步代码。
为什么async await函数前面要有一个async?
为了兼容旧代码,以前有人实现了与async/await功能相同的await函数,例如这样:
await(newPromise())
所以为了做区分,在函数前面增加async以示不同,没有别的特殊含义。
优化async await错误处理
常见的错误处理方法 try/catch
let response
try{
response = await axios.get('/xx')
} catch(err){
if(err.response){
console.log(err.response.states)
}
throw err
}
console.log(response)
这样处理感觉不太好看,我们可以优化一下,结合Promise写出如下代码:
const response = await axios.get('/xx').then(null, err)
console.log(response)
response处理成功结果,then(null, err) 的err处理失败结果。
async/await实际上就是Promise的语法糖。
async await面试题
let a = 0;
let test = async () => {
a = a + await 10;
console.log(a)
}
test()
console.log(++a)
请问log分别会输出什么?
答案:1,10
这里考察的知识点:a + await 10 前面的a 是跟随await一起异步确定的,还是a先确定值。
事实上在await前面的值都会同步执行,await后面的才会异步执行,记住这点就很好理解了。
题目中虽然先log了++a,a值应该为1。但是在test()函数中a + await 10 中的a在test()运行时就已经将值确定了,值为0。
0 + 异步的await 10 等于10。