简述
在平时coding中,有时可能会遇到某些业务场景需要在同一时间只能做一件事,做完了才能做下一件事情。这种很明显符合同步操作的逻辑,但如果不采取某些优雅的编程方式可能就会导致如图这样的结果,很有可能就会产生传说中的回调地狱
。
需求
假设现在有这样一个场景,我们需要去爬取一个网站上的数据,需要先将大致内容爬取下来,再逐步去筛选小部分的内容,再根据小部分的内容去获取具体的资源。如何利用**Promise**
去实现这个需求呢?
1. Promise写法
//模拟需要进行的操作
let option = ["爬取音乐列表api", "爬取单曲id", "根据单曲id爬取具体资源"];
//定义一个通用的请求数据的方法
function getData(option) {
return new Promise((resolve, reject) => {
//利用setTimeout模拟真实网络中的请求速度
setTimeout(() => {
//真实情况Promise里返回的是通过异步请求得到的网络数据,这里暂且用文字提示
resolve("success: " + option);
}, 1000);
})
}
现在就需要我们进行一步又一步地操作了…
执行getData()
函数,由于这个函数返回的是Promise对象,所以可以利用.then()
方法来接收,在.then()
方法中对返回的数据进行处理以后,又在.then()
方法中执行getData()
函数,getData()
函数中传入下一步要操作的内容。以此类推,执行到最后一步操作后,再在最后接上.catch()
方法用于接收前面所有Promise
中可能出现的错误。
//模拟需要进行的操作
let option = ["爬取音乐列表api", "爬取单曲id", "根据单曲id爬取具体资源"];
//定义一个通用的请求数据的方法
function getData(option) {
return new Promise((resolve, reject) => {
//利用setTimeout模拟真实网络中的请求速度
setTimeout(() => {
//真实情况Promise里返回的是通过异步请求得到的网络数据,这里暂且用文字提示
resolve("success: " + option);
}, 1000);
})
}
//写法1:
getData(option[0])
.then(data => {
console.log(data);
// Do something
return getData(option[1]);
})
.then(data => {
console.log(data);
// Do something
return getData(option[2]);
})
.then(data => {
// Do something
console.log(data);
})
.catch(e => {
console.log(e);
})
运行结果如图:
不过除此之外,还有一种优雅的写法,也是现目前利用同步代码解决异步操作的终极版本:async-await
2. async-await写法
在这里就不多介绍它们的基本用法和含义了,直接上操作
/* 定义一个async函数 */
async function load(){
try{
let res1 = await getData(option[0]);
// Do something
console.log(res1);
let res2 = await getData(option[1]);
// Do something
console.log(res2);
let res3 = await getData(option[2]);
// Do something
console.log(res3);
}catch(e){
console.log("error:",e);
}
}
load();
/*---------------------------------------------------------------------------------*/
/* 或者可以通过执行匿名函数方式 */
(async function(){
try{
let res1 = await getData(option[0]);
// Do something
console.log(res1);
let res2 = await getData(option[1]);
// Do something
console.log(res2);
let res3 = await getData(option[2]);
// Do something
console.log(res3);
}catch(e){
console.log("error:",e);
}
})();