Promise
基础用法
function roller() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(Math.floor(Math.random() * 6) + 1)
}, 3000);
})
}
roller().then((data) => {
console.log(data)
}, (err) => {
console.log(err)
})
其他API
- Promise.resolve(result) 制造一个成功(或者失败)
- Promise.reject(reason) 制造一个失败
- Promise.all(数组) 等待全部成功,或者有一个失败
- Promise.race(数组) 等待第一个状态改变
Promise.allSettled(数组) 等待全部状态改变,目前处于State4
应用场景
多次处理一个结果
- 摇色子.then(v=>v1).then(v1=>v2)
- 串行
- 这里有一个悖论:一旦promise出现,那么任务就已经执行了
- 所以不是promise串行,而是任务串行
- 解法:把任务放进队列,完成一个再做下一个
- 并行
- Promise.all([p1,p2]) 不好用
- Promise.allSettled 太新,不好兼容
面试题
页面有两个按钮A和B,以及一个输入框,A按钮点击后发送一个请求,返回一个字符串A,B也发送请求,但返回字符串B,返回后会把字符串赋值给输入框。但是A、B发送的两个请求返回时间不同,点击两个按钮的顺序也不一定,B要比A先返回,二最终效果要求是输入框字符的书序是A B。
图解
解法
Async&Await
常见用法
const fn =async ()=>{
const temp=await makePromise()
return temp + 1
}
有点
封装async
function 摇色子(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(Math.floor(Math.random()*6)+1)
},3000)
})
}
async function fn(){
var result=await 摇色子()
console.log(result)
}
fn()
抛出错误
async function 摇色子(){
throw new Error('出问题')
}
async function fn(){
try{
var result = await 摇色子()
console.log(result)
}catch(e){
console.log(e.message)
}
}
fn()
why need async?
看起来有带点多余,await所在函数就是async,为什么外面还要写async?
细节
- 可以把4xx、5xx等常见错误用拦截器全局处理
- await只用关心成功,失败全部交给errorHandler
- errorHandler也可以放在拦截器里
在then中去处理错误,await只接受成功的结果
ajax = function(){
return new Promise((resolve,reject)=>{
reject({
response:{
status:403
}
})
})
}
var error=(e)=>{
console.log(e)
throw e
}
async function fn(){
const response = await ajax().then(null,error)
console.log(response)
}
fn()
await的传染性
代码
console.log(1)
await console.log(2)
console.log(3)
console.log(3)变异步任务了
- Promise同样有传染性(同步变异步)
-
await的应用场景
多次处理一个结果
- const r1 = await makePromise()
- const r2 = handleR1(r1)
- const r3 = handleR2(r2)
- 串行
- 天生串行
- 循环的时候又bug
- 并行
- await Promise.all([p1,p2,p3]) 就是并行
await 循环
for
- 打开控制台,运行结果为 4 2 1
- 说明 for 循环中的 await 是串行的(后面等前面)
foreach
- 打开控制台,运行结果为 1 2 3
- 说明 forEach 循环中的 await 是并行的(后面不等前面)
题目
答案let a = 0
let test = async () => {
a = a + await 10
console.log(a)
}
test();
console.log(++a)
1
10