[js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

本文主要是介绍[js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js jade express mongodb mongoose promise实现todolist,本文就来讲解下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可以帮你非常灵活的调整:

 1 function next( n ){
 2     return 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 );
10     return next( 2 );
11 } ).then( function( res ){
12     console.log( res );
13     return 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一个值,把一个值往下传递

 1 function next( n ){
 2     return 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 );
10     return 2;
11 } ).then( function( res ){
12     console.log( res );
13     return 3;
14 } ).then( function( res ){
15     console.log( res );
16 } )

reject是把数据传递给then方法的第二个function处理,then方法可以接收2个参数

 1 function next(){
 2     return new Promise( function( resolve, reject ){
 3         var num = Math.floor( Math.random() * 10 );
 4         if ( 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传递的数据

 1 function next(){
 2     return new Promise( function( resolve, reject ){
 3         var num = Math.floor( Math.random() * 10 );
 4         if ( 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主要解决的是多个异步模块的依赖问题,必须等大家都加载完毕之后,才执行( 说白了,就是等最慢的那个异步操作执行完了,再打印出结果 )

 1 var count = 0;
 2 function next() {
 3     return new Promise(function (resolve, reject) {
 4         var 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还有其他的用法,在项目中,这些是比较常用到的

这篇关于[js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076910

相关文章

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

python常见环境管理工具超全解析

《python常见环境管理工具超全解析》在Python开发中,管理多个项目及其依赖项通常是一个挑战,下面:本文主要介绍python常见环境管理工具的相关资料,文中通过代码介绍的非常详细,需要的朋友... 目录1. conda2. pip3. uvuv 工具自动创建和管理环境的特点4. setup.py5.

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字