为什么会有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,不会等待其他的异步操作

作者:ghostwu, 出处:http://www.cnblogs.com/ghostwu

promise的理解的更多相关文章

  1. promise的理解和使用

    1. Promise是什么 1.1 promise 的理解 1. 抽象表达: Promise 是 JS 中进行异步编程的新的解决方案(旧的是纯回调形式) 2. 具体表达: (1)从语法上说:Promi ...

  2. 「每日一题」面试官问你对Promise的理解?可能是需要你能手动实现各个特性

    关注「松宝写代码」,精选好文,每日一题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目类 ...

  3. promise的理解和应用

    老铁们,我又满血复活了,今天我准备来吹一波我对promise,如有错吴请直接指出,明白了吗?话不多说开始吧 首先我们需要知道啥叫promise,我问了问大佬,他说这个东西是 异步操作的同步代码(but ...

  4. 谈谈你对Promise的理解

    一.Promise是什么? 理解 抽象表达: Promise 是一门新的技术(ES6 规范) Promise 是 JS 中进行异步编程的新解决方案(备注:旧方案是单纯使用回调函数) 具体表达: 从语法 ...

  5. 对Promise的理解?

    ES6原生提供了promise对象 所谓Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通过是一个异步操作),并且这个事件提供统一的API,可供进一步处理 P ...

  6. 一点对Promise的理解与总结

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10959411.html,多谢,=.=~ axios用多了就开始疑惑它里面到底是个啥,虽然总被告知 ...

  7. 谈谈我对Promise的理解

    一.Promise是什么? Promise是最早由社区提出和实现的一种解决异步编程的方案,比其他传统的解决方案(回调函数和事件)更合理和更强大. ES6 将其写进了语言标准,统一了用法,原生提供了Pr ...

  8. 简单理解ECMAScript2015中的Promise

    ECMAScript6中新增了Promise对象, 所谓Promise对象,即代表着一个还未完成,但将来某时会完成的操作(通常是异步操作).使用Promise对象,我们就可以避免陷入函数层层嵌套的‘回 ...

  9. 深入理解promise

    如今promise大行其道,关于异步方面的几乎都有它的影子,新的fetch api返回的是promise对象,generator中的yield后面一般也会跟promise对象,async的await后 ...

随机推荐

  1. LeetCode第十六题-找出数组中三数之和最接近目标值的答案

    3Sum Closest 问题简介: 给定n个整数的数组nums和整数目标,在nums中找到三个整数,使得总和最接近目标,返回三个整数的总和,可以假设每个输入都只有一个解决方案 举例: 给定数组:nu ...

  2. JMX - JMX定义

    JMX定义 JMX超详细解读 https://www.cnblogs.com/dongguacai/p/5900507.html 开源框架是如何通过JMX来做监控的(一) - JMX简介和Standa ...

  3. babel-polyfill的几种使用方式

    前言 preset与plugin的关系: preset中已经包含了一组用来转换ES6+的语法的插件,如果只使用少数新特性而非大多数新特性,可以不使用preset而只使用对应的转换插件 babel默认只 ...

  4. IIS 运行ASP.Net的基本配置(编辑中。。。)

    今天在新建的IIS上运行Asp.net 程序,发现IIS根本没有走asp的路由系统,直接返回了404,后来发现是IIS没有正确安装,需要安装以下的组件: 未安装前,IIS里的样子: 安装后,IIS的样 ...

  5. MySQL时区错误导致server time zone value 'Öйú±ê׼ʱ¼ä' 错误

    时区错误 由于中国是东八区,跟mysql配置不同,需要修改: 管理员登录MySQL OK成功

  6. Lesson 2-2(列表,元组)

    2.3 列表 2.3.1 列表的创建方法 --- 使用方括号 [] ,括号中的元素之间使用逗号隔开. >>> [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] > ...

  7. java.lang.IllegalArgumentException: Invalid source 'classpath:spring-mvc.xml'

    今天在跑项目时遇到java.lang.IllegalArgumentException: Invalid source 'classpath:spring-mvc.xml'报错,自己也是摸索了很久,一 ...

  8. 前言:JNI调用-简单使用

    JNI JNI是(Java Native Interface  本地接口)是一个协议,用来沟通Java 代码和C/C++代码,是 Java和 C.C++之间的桥梁. 通过JNI协议,Java可以调用外 ...

  9. MVC Bundle生成的css路径问题

    项目是嵌套在主站的一个子站点,结果用CssRewriteUrlTransform来将相对目录路径改成相对网站根目录路径的时候发现少了虚拟目录的路径.最终解决方案: /// <summary> ...

  10. rpm和yum软件管理

    rpm简介 数据库管理工具,通过读取数据库,判断软件是否安装,如已安装可读取出来所有文件的所在位置等,并可以实现删除这些文件. rpm:RPM is Redhat Package Manager(递归 ...