一、回调地狱
getMoreData(a,b => {
getMoreData(b,c => {
getMoreData(c,d => {
getMoreData(d,e => {
console.log('e');
})
})
})
})
})
二、Promise改进回调地狱
.then(a => getMoreData(a))
.then(b => getMoreData(b))
.then(c => getMoreData(c))
.then(d => getMoreData(d))
.then(e => console.log(e));
一般是用一个函数嵌套,返回一个promise对象,为什么这么用?
因为then,catch方法需要一个Promise实例,才能把多个异步执行的操作,根据resolve和reject的执行状态一层层往下执行.
当我们执行next( 1 )的时候,在next函数中返回一个promise对象,一秒钟之后,通过resolve把n( 就是 1 )传递给then方法的第一个function,参数res就是resolve传递过来的数据,所以1秒钟后输出1,紧接着我在return next( 2 ),这个时候又调用了一次Promise对象,一秒钟后,通过resolve把n ( 就是 2 )传递给下一个then方法的第一个function, 参数res就收到n( 2 )的值,所以1秒钟后输出2。。。下面输出3的过程跟刚才分析的一样,有一点一定要注意,在then方法中的function 调用的next方法,一定要用return ,否则不会通过resolve把数据往下传递( 通俗点讲就是下一个异步操作,接收不到上一步的结果 ).
then中的function也可以return一个值,把一个值往下传递
function next( n ){
return new Promise( function( resolve, reject ){
setTimeout( function(){
resolve( n );
}, 1000 );
} );
}
next( 1 ).then( function( res ){
console.log( res );
return 2;
} ).then( function( res ){
console.log( res );
return 3;
} ).then( function( res ){
console.log( res );
} )
reject是把数据传递给then方法的第二个function处理,then方法可以接收2个参数
function next(){
return new Promise( function( resolve, reject ){
var num = Math.floor( Math.random() * 10 );
if ( num <= 5 ) {
resolve( num );
}else {
reject( new Error() );
}
} );
}
next( 1 ).then( function( res ){
console.log( res );
}, function( res ){
console.log( res );
} );
console.log( '正常执行' );
catch也是接收reject传递的数据
function next(){
return new Promise( function( resolve, reject ){
var num = Math.floor( Math.random() * 10 );
if ( num <= 5 ) {
resolve( num );
}else {
reject( new Error() );
}
} );
}
next( 1 ).then( function( res ){
console.log( res );
} ).catch( function( res ){
console.log( 'reject:' + res );
} );
console.log( '正常执行' );
**Promise.all是等所有的异步资源都加载完毕之后,再执行代码,**比如。页面有很多的插件库,一般都是要加载完毕之后,才能有特效效果。Promise.all主要解决的是多个异步模块的依赖问题,必须等大家都加载完毕之后,才执行( 说白了,就是等最慢的那个异步操作执行完了,再打印出结果 )
function next() {
return new Promise(function (resolve, reject) {
var num = Math.floor(Math.random() * 10);
setTimeout( function(){
console.log( num );
resolve( `第${++count}随机到的值是${num}`);
}, 2000 );
});
}
Promise.all( [ next(), next(), next() ] ).then( function( res ){
console.log( res );
} );//三个next()异步操作执行完毕之后,才会一起把他们的resolve结果打印出来
三、async/await改进Promise
const a = await getData(a);
const b = await getData(b);
const c = await getData(c);
const d = await getData(d);
const e = await getData(e);
console.log(e);
})();
await接收一个Promise对象。后面的函数必须是Promise对象。
Paromise和async/await的应用场景是大量连续的异步操作。
所以,
exec(..., function () {
if(sucess){
resolve();
} else {
reject();
}
})
})
await会暂停当前async函数的执行,等待后面的Promise的计算结果返回再继续执行async函数。
async/await是Promise和Generator的语法糖。也就是async/await是建立在Promise之上的,Promise并没有失去地位。
在每一个函数前面的都加上async,函数内部,如果是异步操作,直接在其前面加上await即可
async/await虽然改进了Promise,但是还是存在缺点的,async/await是把双刃剑这篇文章很好介绍了。