举个例子,有一个需求是按序加载数据,加载完数据a,才能加载数据b,加载完数据b才能加载数据c,依次类推.....
先上需求代码
function requestA(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("拿到的数据a");
},3000)
});
}
function requestB(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("拿到的数据b");
},2000)
});
}
function requestB(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve("拿到的数据c");
},1000)
});
}
定时器用来模拟请求数据所需的时间。
再上解决代码
console.log("我是开头");
requestA().then((data)=>{
console.log(data);
return requestB();
}).then((data)=>{
console.log(data);
return requestC();
}).then((data)=>{
console.log(data);
});
console.log("我是结尾");
Nodejs或者浏览器中的js环境都是先运行同步代码,碰见异步代码将其放进一个容器中,等待条件OK再执行(涉及到两种不同环境下js的Evenloop,这里只粗略涉及,详细内容在另一篇文章中)
就上面的简单情况而言,可以先这么简单理解: 先执行同步代码,再执行异步代码。
分析代码执行流程
1.遇到同步代码console.log("我是开头"),直接输出"我是开头"。
2.requestA()返回其对应的Promise对象,因为该对象内的代码是异步代码, 所以先将其放入异步容器中。返回的Promise对象中的resolve没有执行,所以后面的then方法也不执行。
3.遇到同步代码console.log("我是结尾"),
控制台输出
我是开头
我是结尾
4.等待三秒后,容器中的异步代码满足执行条件,执行resolve(),改变Promise对象状态为成功,执行第一个then()方法,
控制台输出
我是开头
我是结尾
拿到的数据a
5.返回requestB()所产生的Promise对象,继续执行第四步(把三秒改成两秒)
控制台输出
我是开头
我是结尾
拿到的数据a
拿到的数据b
6.返回requestB()所产生的Promise对象,继续执行第四步(把三秒改成一秒),流程执行完毕
最终控制台输出:
我是开头
我是结尾 (等待三秒)
拿到的数据a (等待两秒)
拿到的数据b (等待一秒)
拿到的数据c