之前已经学过了promise,promise带来的好处其实主要有两个。第一个是消除了回调地狱,但是实际上它是没有消除回调,该写的回调函数一个也没少写。第二个是它形成了一种大家公认的处理异步的规范,当形成了大家都采用这种处理方式之后,也就为官方组织提供对其进一步优化的可能性,这就引出了本节课所要学习的async和await关键字。
ES7推出了两个关键字async和await,用于更加优雅的表达Promise
async
async关键字用于修饰函数,被它修饰的函数,一定返回Promise
async function method1(){
return 1; // 该函数的返回值是Promise完成后的数据
}
method1(); // Promise { 1 }
async function method2(){
return Promise.resolve(1); // 若返回的是Promise,则method得到的Promise状态和其一致
}
method2(); // Promise { 1 }
async function method3(){
throw new Error(1); // 若执行过程报错,则任务是rejected
}
method3(); // Promise { <rejected> Error(1) }
await
await关键字表示等待某个Promise完成,它必须用于async函数中
async function method(){
const n = await Promise.resolve(1);
console.log(n); // 1
}
// 上面的函数等同于
function method(){
return new Promise((resolve, reject)=>{
Promise.resolve(1).then(n=>{
console.log(n);
resolve(1)
})
})
}
await也可以等待其他数据
async function method(){
const n = await 1; // 等同于 await Promise.resolve(1)
}
如果需要针对失败的任务进行处理,可以使用try-catch语法
async function method(){
try{
const n = await Promise.reject(123); // 这句代码将抛出异常
console.log('成功', n)
}
catch(err){
console.log('失败', err)
}
}
method(); // 输出: 失败 123
之前表白的完美解决方案
帅哥程序员的女神可不是只有4位,而是40位!
为了更加方便的编写表白代码,帅哥程序员决定把这40位女神放到一个数组中,然后利用async和await轻松完成代码
// 女神的名字数组
const beautyGirls = [
"Emma", "Olivia", "Ava", "Sophia", "Isabella",
"Mia", "Charlotte", "Amelia", "Ella", "Avery",
"Evelyn", "Abigail", "Emily", "Elizabeth", "Mila",
"Grace", "Chloe", "Zoey", "Natalie", "Scarlett",
"Victoria", "Madison", "Luna", "Aria", "Hazel",
"Aubrey", "Addison", "Layla", "Zoe", "Nora",
"Lily", "Morgan", "Brooklyn", "Savannah", "Penelope",
"Riley", "Aaliyah", "Leah", "Audrey", "Stella"
];
// 向某位女生发送一则表白短信
// name: 女神的姓名
function sendMessage(name) {
return new Promise((resolve, reject) => {
// 模拟 发送表白短信
console.log(
`帅哥程序员 -> ${name}:最近有谣言说我喜欢你,我要澄清一下,那不是谣言😘`
);
console.log(`等待${name}回复......`);
// 模拟 女神回复需要一段时间
setTimeout(() => {
// 模拟 有10%的几率成功
if (Math.random() <= 0.1) {
// 成功,调用 onFuffiled,并传递女神的回复
resolve(`${name} -> 帅哥程序员:我是九,你是三,除了你还是你😘`);
} else {
// 失败,调用 onRejected,并传递女神的回复
reject(`${name} -> 帅哥程序员:你是个好人😜`);
}
}, 1000);
});
}
// 批量表白的程序
async function proposal() {
let isSuccess = false;
for (const girl of beautyGirls) {
try {
const reply = await sendMessage(girl);
console.log(reply);
console.log('表白成功!');
isSuccess = true;
break;
} catch (reply) {
console.log(reply);
console.log('表白失败');
}
}
if (!isSuccess) {
console.log('帅哥程序员注定孤独一生');
}
}
proposal();
练习题
- 1.完成delay函数
// 完成delay函数
// 该函数可以等待一段指定的时间
// 返回Promise
function delay(duration) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, duration);
});
}
// 利用delay函数,等待3次,每次等待1秒,每次等待完成后输出ok
// 等待1秒->ok->等待1秒->ok->等待1秒->ok
(async () => {
for (let i = 0; i < 3; i++) {
await delay(5000);
console.log('ok');
}
})();