此文章主要讲解核心思想和基本用法,想要了解更多细节全面的使用方式,请阅读官方API 这篇文章假定你具备最基本的异步编程知识,例如知道什么是回调,知道什么是链式调用,同时具备最基本的单词量,例如page、user、promise、then、resovle、reject、pay、fix、order等等,如果你对这些单词非常陌生,那么你需要先花点时间补充一下你的英语

什么是异步操作?

所谓异步操作,指的是可以跟当前程序同时执行的操作。举例:

$("#page").scrolltop(0 ,1000);    //使用1秒钟时间将页面滚动至顶部
$("#nav-float").hide (1000);    //使用1秒钟时间将悬浮导航栏隐藏

只要你稍微有点异步编程经验,就应该知道,这两个方法会同时完成。

它们的编写顺序并不会影响它们的执行顺序

//异步操作的特点就是,不会打断当前程序的执行//getUsers请求发出后,会立刻向下继续执行第二个请求
ajax("/getUsers",function(data) {//回掉函数会在请求成功后调用
})
//resumelist请求会立刻开始,无论getUsers是否结束
ajax("/resumelist", function(data) {})
//至于哪一个ajax先返回结果并执行回调函数,从代码的编写顺序上是无法确定的。

我们可以给异步操作做一个简单的定义

当一个操作开始执行后,主程序无需等待它的完成,可以继续向下执行。此时该操作可以跟主程序同时(并发)执行。这种操作我们就称之为异步操作。 通常当操作完成时,会执行一个我们事先设定好的回调函数来做后续的处理。

我们常见的异步操作例如:

添加定时器 setTimeout/setInterval

执行某个动画 animate

发起网络请求 request

异步会带来什么问题?

比如我们现在有两个动画,需要按顺序来执行,也就是第一个结束,第二个才能开始 这个时候可能有点麻烦,传统的解决方法是通过回调:

animateA(function( ){animateB( );
})      

这种方案显然不太好,如果有很多异步操作需要顺序执行,就会产生所谓的“回调地狱”

ajaxA(function( ){ajaxB(function( ){ajaxC(function( ){ajaxD(function( ){......   }); }); });
}) 

这种代码不管是写起来还是读起来都比较烦人。

我们来看下经过Promise改造后的样子(伪代码)

newPromise(ajaxA).then(ajaxB).then(ajaxC).then(ajaxD);  

Promise的使用及原理

要熟练Promise的的使用,你必须要先搞懂它解决问题的原理 贴一段实际的Promise代码,你来感受一下先:

newPromise(resolve=>{ajax("/pay/post", data=>resolve() );
}).then(resolve=>{ajax("/order/fix", data=>{//处理数据   })
})

上面的代码使用了ES6的箭头函数,虽然大大简化了代码的写法,

但对于初级程序猿来讲极不友好

读这种代码简直跟读金刚经差不多。

我们把代码还原成ES5的样子

newPromise(function(resolve){ajax("/pay/post",function(data){resolve();})
}).then(function(){ajax("/order/fix",function(data){})
})

接下来,我们就按照费曼技巧来一步步的学习Promise是如何解决问题的

问题1, 作为一个异步函数,尤其像ajax这种网络请求,连我自己都不能确定函数的执行时间,Promise是怎么知道第一个函数什么时候结束的? 然后再开始执行下一个?

Promise并没有那么神奇,它并不能知道我们的函数什么时候结束,
你注意到上面代码中的第3行了吗
在ajax请求结束执行回调的时候,
我们调用了一个resolve()函数,这句代码非常的关键.
这其实就是在通知Promise,当前这个函数结束啦,
你可以开始执行下一个。 这时Promise就会去执行then里面的函数了。

问题2, 所以按照你的意思,如果我不调用这个方法,Promise就不知道这个函数有没有结束,那么then里面的函数就不会执行,也就是说我的第二个请求就永远不会发送了呗?

Bingo!! 恭喜你已经学会了逻辑推理+抢答。

问题3, 可是这个resolve函数是从哪来的? 需要我自己定义吗? 从代码上看它好像是个参数,那又是谁传入函数中的?

你得先弄明白Promise的基本结构
newPromise(函数1).then(函数2);我们把函数1和函数2都以参数形式传给了一个Promise对象,
所以接下来函数1和2都会由这个Promise对象控制,
简单的说,函数1和函数2都会由Promise对象来执行。
所以在函数1执行时,参数也当然是由Promise对象传递进去的。newPromise(function(resolve){//resolve是Promise对象在调用函数时传入的参数
}).then(函数2);

问题4, Promise对象为啥要在执行第1个任务的时候,把这个resolve函数 传进来,有什么目的?

你说呢?

废屁,知道还用问你?

真是猪脑子,刚才不是已经说了吗?
Promise对象没办法知道我们的异步函数啥时候结束。
那我来问你, 如果你去车站接人,
可是你又不知道对方何时下车,你会咋办?

把我电话号码给他,快到了打我电话呗

没错,Promise解决问题也采用了同样的思路。
它传进来的resolve函数, 就好像一个对讲机,
当我们的异步任务要结束时,通过对讲机 来通知Promise对象。
也就是调用resolve方法newPromise(function(resolve){ajax("/pay/post",function(data){//当请求结束时,通过调用resolve方法,通知Promise对象,该任务已完成resolve(); //收到通知后,Promise会立刻开始函数2的执行})
}).then(函数2);

懂了,所以这个resolve函数,必须在异步任务的最后调用(例如ajax的回调方法),相当于告诉Promise对象,该任务结束,请开始下一个。

完全正确

问题5, 所以Promise也不过如此嘛,它没有带来什么功能上的革命性变化, 因为使用传统的回调嵌套的方式,同样可以完成效果。 说白了它就是编码方式上的改进??

基本是这样的,但Promise带来的编码方式以及异步编程思路上的进步是非常巨大的。

问题6, 那如果我有ajaxA、ajaxB、ajaxC三个异步任务,想按照先A后B再C的顺序执行,像这样写行吗?

newPromise(function(resolve){ajax("/AAA", function(){resolve(); //通知Promise该任务结束})
}).then(function(resolve){ajax("/BBB", function(){resolve();//通知Promise该任务结束})
}).then(function(){ajax("/CCC", function(){ //.... })
})  
上面的这种写法是不对的。
Promise的中文含义是“承诺”,
则意味着,每一个Pormise对象,代表一次承诺
而每一次承诺,只能保证一个任务的顺序,也就是说
newPromise(A).then(B); 这句话表示, 只能保证A和B的顺序一旦A执行完,B开始后,这次承诺也就兑现了,Promise对象也就失效了
那如果还有C呢? 我们就必须在函数B中,
重新创建新的Promise对象,来完成下一个承诺,具体的写法就像这样:newPromise(函数1(resolve){ajaxA("xxxx", function(){resolve();//通知Promise该任务结束})
}).then(函数2(){//在函数2开始运行后,第一次创建的Promise对象完成使命,已经不能再继续工作。//此时,我们创建并返回了新的Promise对象returnnewPromise(function(resolve){ajaxB("xxxx", function(){resolve();//通知新的Promise对象该任务结束})    })
}).then(函数3(){ //尽管这里使用了链式调用,但负责执行函数3的,已经是新的Promise对象了// 如果,我们还有ajaxD需要顺序调用// 那就必须在这里重新new Promise()对象了ajaxC("xxx", function(){     })
})   

问题7, 懂了,那Promise还有什么其它强大的功能吗?

有啊,例如: 如果我有 A,B,C 三个异步任务,ABC同时开始执行
当A,B,C三个任务全部都结束时,执任务D,
传统方法实现起来就比较复杂,Promise就非常简单,就像这样:Promise.all([newPromise(A), newPromise(B), newPromise(C)])
.then(function(){D();
});

问题8, 那如果我希望A,B,C 其中任意一个任务完成, 就马上开始任务D,该怎么做?

Promise.race([newPromise(A), newPromise(B), newPromise(C)])
.then(function(){D();
});

Promise的使用及原理相关推荐

  1. 异步编程之Promise(2):探究原理

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  2. Promise.all实现原理

    Promise.all的使用 1.使用特征 入参是一个数组,可以传基本类型值,也可以传promise对象. 返回结果是一个Promise对象. 入参数组中的每一个都返回成功,才返回成功. 只要有一个执 ...

  3. 自己动手写cpu pdf_自己动手写 Promise

    这段时间在学习Promise,但始终不得要领.为了更好地理解Promise,我决定自己实现一个简易版的Promise,以学习Promise工作原理.该工程名为ToyPromise,仓库地址如下: ht ...

  4. promise的状态以及api介绍_Promise从入门到自定义 | 尚硅谷Promise新版视频发布!

    尚硅谷发布全新升级版前端课程,推出"5+100+3"人才培养新模式,5.5个月系统学习+100课时进阶课程+3年谷粒学院VIP课程,为技术成长持续赋能,打造前端架构师!预知详情,猛 ...

  5. 谈谈我对Promise的理解

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

  6. es5如何实现promise_彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)...

    众所周知javascript语言的一大特色就是异步,这既是它的优点,同时在某些情况下也带来了一些的问题.最大的问题之一,就是异步操作过多的时候,代码内会充斥着众多回调函数,乃至形成回调金字塔.为了解决 ...

  7. Promise和事件循环

    01-Promise语法 1.1-Promise介绍 ES6教程传送门:http://es6.ruanyifeng.com/#docs/promise 1.Promise是什么? Promise 是 ...

  8. JQuery原理解析

    原文博客链接 藤原拓鞋的博客 开始 本文仅对 jQuery 基本的 API 及其原理进行分析,源代码一万多行并没有完整分析,仅作参考 jQuery 无 new 创建实例 jQuery 共享原型的设计思 ...

  9. Promise语法处理回调地狱

    一.什么是回调地狱 setTimeout(function () { //第一层console.log(111);setTimeout(function () { //第二程console.log(2 ...

最新文章

  1. 文章推荐 | 城市规划中城市信息学的研究进展
  2. WPF自定义控件(1)——仪表盘设计[1]
  3. 软件架构设计 导言
  4. WINCE系统启动时是否clean boot
  5. 学习Winform了解到switch和if-else的妙处
  6. 验证gpu版pytorch是否可用
  7. 虚拟专题:知识图谱 | 医学知识图谱构建关键技术及研究进展
  8. mysql权限相关操作
  9. 【C语言】一维数组排序(函数,数组和循环结构语句)
  10. sql server 比较大小
  11. 每日算法系列【LeetCode 329】矩阵中的最长递增路径
  12. php cmyk转rgb,用PHP将CMYK格式的JPG文件转为RGB格式 | 学步园
  13. Win300英雄服务器不显示,win10系统玩不了300英雄的还原步骤
  14. 草莓换个做法,迫不及待想要吃
  15. php smarty extends,php封装的smarty类完整实例
  16. 嵌入式系统开发-麦子学院(11)——ARM Cortex A8 硬件基础(1)
  17. GIS应用技巧之景观格局分析(二)
  18. android menu 键值,Android KeyCode安卓手机按键对应键码键值
  19. 将一个自然数拆分为N个自然数
  20. linux 系统级性能分析工具 perf 的介绍与使用

热门文章

  1. 高反差保留阈值——素描效果——鸟儿
  2. US Domain Center 网站备份
  3. 微信公众号接入天行机器人案例和方法
  4. python小练习~绘制等边三角形,四边形,五角形,六角形等
  5. 人工鱼群算法python_鱼群算法 - Brillou的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. png的计算机储存图片的格式吗,png图片怎样转换成jpg格式
  7. ARM_s5pv210_arm_9
  8. ViewModel 必知的几个问题
  9. 从一个三维数组中挑出最大值
  10. (郁闷p2pover中)整理记录三