一、Promise
一个掷骰子游戏,小于等于3判定为小,大于3判定为大,1.5s后出结果,与猜测值对比。
function game(guess) {
return new Promise((reslove, reject) => {
setTimeout(() => {
let n = parseInt(Math.floor(Math.random() * 6) + 1);
if (n > 3) {
if (guess === '大') {
reslove('你猜大……点数是大,猜对了,结果是:' + n);
} else {
reject('你猜小……但是点数是' + n + ',猜错了!');
}
} else {
if (guess === '小') {
reslove('你猜小……点数是小,猜对了,结果是:' + n);
} else {
reject('你猜大……但是点数是' + n + ',猜错了!');
}
}
}, 1500)
})
}
二、.then()
Promise 实例有一个 then 方法,用来处理 Promise 完成或拒绝状态下的结果,成功时走成功的回调函数,失败时走失败的回调函数。
let res1 = game('大')
.then((res) => {
console.log(res);
}, (err) => {
console.log(err);
})
let res2 = game('小')
.then((res) => {
console.log(res);
}, (err) => {
console.log(err);
})
三、Promise.all()
传入一个迭代对象,比如放一组 promise 请求。只有在所有请求都成功才会继续执行成功回调,如果遇到失败就执行它的第一个失败回调。
let res3 = Promise.all([game('大'), game('小')])
.then(res => {
console.log(res);
}, err => {
console.log(err);
})
四、Promise.race()
与 Promise.all() 的不同在于执行那个最先响应的请求,不管它是否成功,只关注谁先响应。
五、async await
async 顾名思义,异步。它是 Promise 的语法糖。
形如 async function name ([param, ...]) { statements } 的函数就是异步函数,执行这个异步函数返回的结果是一个 Promise。
await 只能写在 async 函数内部,一旦写在内部,就相当于对 Promise 的 resolve 或者 reject 结果进行 .then() 操作。
异常捕获用 try catch。
async function test() {
try {
let res1 = await game('大');
console.log(res1);
} catch(err) {
console.log(err);
}
}
test();
其中,let res1 = await game('大') 分两步。
第一步是 await game('大'),也就是等待 game('大') 的异步请求,这一步相当于执行:game('大').then(res=>{...}, err => {...}),
第二步是拿到结果后,let res1 = 异步结果; 也就是将结果赋值给 res1 。
六、async 函数中处理多请求
await 后面本来就是写 Promise 结果的地方,把 Promise.all([...]) 写在 await 后面即可。
相当于 let res = Promise.all([...]).then(...)
async function test2() {
try {
let res = await Promise.all([game('大'), game('小')]);
console.log(res);
console.log('很好,都请求成功了!');
} catch(err) {
console.log(err);
}
}
七、总结
-
Promise 用于异步编程,解决回调地狱问题。
-
Promise 的参数是一个处理函数,这个函数接收两个参数(都是函数),一个是reslove,一个是reject。
-
resolve 调用时,将promise状态改为fulfilled(完成),reject调用时,将promise状态改为rejected(失败)。
-
.then 方法用于处理promise不同状态下的值,当在fulfilled状态时,调用成功的回调函数;当在rejected状态时,调用失败的回调函数。
-
.then() 操作后,再次返回一个Promise对象,这就是为什么它可以进行链式调用的原因。
-
Promise.all() 都成功才成功
-
Promise.race() 谁跑得最快返回谁
-
Promise.finally() 不管成功还是失败,都执行回调
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise