[js⾼⼿之路]es6系列教程-promise常见⽤法详解
(resolve,reject,。。。
关于promise我在之前的⽂章已经应⽤过好⼏次,如,本⽂就来讲解下promise的常见⽤法.
为什么会有promise,他的作⽤是什么?
promise主要是为了解决js中多个异步回调难以维护和控制的问题.
什么是promise?
从图中,我们可以看出,Promise是⼀个函数,这个函数上有在项⽬中常⽤的静态⽅法:all, race, reject,resolve等,原型对象上有有catch, then等⽅法.也就是说,如果要调⽤catch和then⽅法,需要⼀个Promise的实例( new Promise ), ⽽静态⽅法可以⽤函数本⾝调⽤,如:Promise.all, Promise.race等,好了,⾄此,⾄少知道Promise是什么,但是还是不知道怎么⽤他提供的⽅法,接下来我们从⼀个需求开始,在javascript中,经常有这样的需求:
1,页⾯上有⼀个按钮,⼀个ul,点击按钮的时候,每隔1秒钟向ul的后⾯追加⼀个li, ⼀共追加10个,li的内容从0开始技术( 0, 1, 2, ....9 ),这个在我的博客中,出现好⼏次
2,每隔1秒钟输出递增的数字,如( 1, 2, 3, 4, 5 等 )
3,红绿灯( 红->(等2秒)->绿( 等2秒 )->黄( 等2秒 ) -> 红等,如此循环下去
4,node.js中的爬⾍,爬⽂章url->爬⽂章内容->爬⽂章url->爬⽂章内容
好了,太多这类应⽤了,这类应⽤叫做异步回调(执⾏完⼀件事,才能接着往下执⾏),如果出现多次,就会产⽣多层嵌套( 回调地狱 ),维护和控制异步过程⾮常的⿇烦和困难,如:
每隔1秒钟输出递增的数字,如( 1, 2, 3 等 )
1 setTimeout(function () {
2 console.log(1);
3 setTimeout(function () {
4 console.log(2);
5 setTimeout(function () {
6 console.log(3);
7 }, 1000);
8 }, 1000);
9 }, 1000);
这还是3层,如果4层,5层。。。。,现在代码简单,可能感觉不到,如果console.log换成具体的业务逻辑,那就不得了,假如每个真实的业务逻辑有100⾏代码,5层嵌套。⽽业务逻辑中⼜有很多的嵌套匹配。你能想象吗?如果由于业务需求需要调换业务的执⾏顺序?是不是很头疼?不⽤担⼼,Promise可以帮你⾮常灵活的调整:
1function next( n ){
2return new Promise( function( resolve, reject ){
3 setTimeout( function(){
4 resolve( n );
5 }, 1000 );
6 } );
7 }
8 next( 1 ).then( function( res ){
9 console.log( res );
10return next( 2 );
11 } ).then( function( res ){
12 console.log( res );
13return next( 3 );
14 } ).then( function( res ){
15 console.log( res );
16 } )
Promise的构造函数接收⼀个参数,是函数,并且传⼊两个参数:resolve,reject,分别表⽰异步操作执⾏成功后的回调函数和异步操作执⾏失败后的回调函数。按照标准来讲,其实resolve是将Promise的状态置为fullfiled,reject是将Promise的状态置为rejected,promise的常⽤⽤法.
⼀般是⽤⼀个函数嵌套,返回⼀个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⼀个值,把⼀个值往下传递
1function next( n ){
2return new Promise( function( resolve, reject ){
3 setTimeout( function(){
4 resolve( n );
5 }, 1000 );
6 } );
7 }
8 next( 1 ).then( function( res ){
9 console.log( res );
10return 2;
11 } ).then( function( res ){
12 console.log( res );
13return 3;
14 } ).then( function( res ){
15 console.log( res );
16 } )
reject是把数据传递给then⽅法的第⼆个function处理,then⽅法可以接收2个参数
1function next(){
2return new Promise( function( resolve, reject ){
3var num = Math.floor( Math.random() * 10 );
4if ( num <= 5 ) {
5 resolve( num );
6 }else {
7 reject( new Error() );
8 }
9 } );
10 }
11 next( 1 ).then( function( res ){
12 console.log( res );
13 }, function( res ){
14 console.log( res );
15 } );
16 console.log( '正常执⾏' );
当随机数⼤于等于6的时候,我把⼀个错误往下抛,然后在then的第⼆个参数接收到,整个程序还是能够正常运⾏.
catch也是接收reject传递的数据
1function next(){
2return new Promise( function( resolve, reject ){
3var num = Math.floor( Math.random() * 10 );代码运行js特效
4if ( num <= 5 ) {
5 resolve( num );
6 }else {
7 reject( new Error() );
8 }
9 } );
10 }
11 next( 1 ).then( function( res ){
12 console.log( res );
13 } ).catch( function( res ){
14 console.log( 'reject:' + res );
15 } );
16 console.log( '正常执⾏' );
Promise.all是等所有的异步资源都加载完毕之后,再执⾏代码,⽐如。页⾯有很多的插件库,⼀般都是要加载完毕之后,才能有特效效果。Promise.all主要解决的是多个异步模块的依赖问题,必须等⼤家都加载完毕之后,才执⾏( 说⽩了,就是等最慢的那个异步操作执⾏完了,再打印出结果 )
1var count = 0;
2function next() {
3return new Promise(function (resolve, reject) {
4var num = Math.floor(Math.random() * 10);
5 setTimeout( function(){
6 console.log( num );
7 resolve( `第${++count}随机到的值是${num}`);
8 }, 2000 );
9 });
10 }
11 Promise.all( [ next(), next(), next() ] ).then( function( res ){
12 console.log( res );
13 } );
三个next()异步操作执⾏完毕之后,才会⼀起把他们的resolve结果打印出来
Promise.race,只要最快的异步执⾏完毕之后,就执⾏then,不会等待其他的异步操作
Promise还有其他的⽤法,在项⽬中,这些是⽐较常⽤到的
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论