题目:第1秒红灯亮,第2秒黄灯亮,第3秒蓝灯亮;如何让三个灯不断交替重复亮灯?(用Promise实现)
不使用Promise
按照逻辑依次执行:首先是红灯亮,调用黄灯亮;黄灯亮,调用蓝灯亮;蓝灯亮,再调用红灯亮...可以看到循环回调的现象。
function lightRed() {
setTimeout(()=>{
console.log("red");
lightYellow();
}, 1000);
}
function lightYellow() {
setTimeout(()=>{
console.log("yellow");
lightBlue();
}, 1000)
}
function lightBlue() {
setTimeout(()=>{
console.log("blue");
lightRed();
}, 1000)
}
lightRed();
使用Promise
对上面代码进行封装
function light(color, delay) {
return new Promise(resolve => {
setTimeout(()=>{
console.log(color);
resolve();
}, delay)
})
}
//很容易想到下面的代码
light("red", 1000).then(()=>{
light("yellow", 1000).then(()=>{
light("blue", 1000).then(()=>{
})
})
})
//或者链式调用
light("red", 1000).then(()=>{
return light("yellow", 1000);
}).then(()=>{
return light("blue", 1000);
})
这样我们只能执行一次;怎么可以循环多次呢?那就是封装成一个函数,在这个函数中调用自己。
const promiseLoop = ()=>{
light("red", 1000).then(()=>{
return light("yellow", 1000);
}).then(()=>{
return light("blue", 1000);
}).then(()=>{
promiseLoop();
})
}
promiseLoop();
async await升级版
const loop = async ()=>{
await light("red", 1000);
await light("yellow", 1000);
await light("blue", 1000);
loop();
}
loop();
通过对比,我们不难发现 async await 比 Promise 更容易理解。这里多补充一些:
async 函数返回一个 Promise 对象;
async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。
async function f() {
return "hello async"
}
f().then(res=>{
console.log(res)
})
对比 Promise 的写法:
function f() {
return new Promise(resolve => {
resolve("hello promise");
})
}
f().then(res=>{
console.log(res)
})
可以看到没有await的async和Promise实现同样的效果。
await只能用在async函数内部,不能单独使用。
await相当于 new Promise(resolve=>{}).then()
类比使用例子:
let result = f(10).then(res=>{
console.log("promsie2: "+ res);
return 2 * res;
}).then(res=>{
console.log("promise3: "+res);
return 3 * res;
});
result.then(res=>{
console.log(res);
});
async function test() {
let res1 = await f(10);
console.log(res1)
let res2 = await f(res1*2);
console.log(res2);
}
test();
可以看出,由于await的存在使得 promise的then方法使用更加灵活。没有await我们只能在前一个then方法中调用另外一个方法;await的存在可以获取 then 里面的返回值,作为下一步灵活使用。