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 = 0let test = async () => {a = a + await 10console.log(a)}test();console.log(++a)
1
10

