帮你理清学习一个知识点的过程

注意:这篇文章的目的是让你用最快的速度理解 Promise 的核心思想和基本用法,想要了解更多细节全面的使用方式,请阅读官方 API
另外:这篇文章假定你具备最基本的异步编程知识,例如知道什么是回调,知道什么是链式调用,同时具备最基本的单词量,例如 page、user、promise、then、resovle、reject、pay、fix、order 等等,如果你对这些单词非常陌生,那么你需要先花点时间补充一下你的英语,否则你仍然会感觉这篇文章难以理解。
什么是异步操作?
所谓异步操作,指的是可以跟当前程序同时执行的操作。举例:
只要你稍微有点异步编程经验,就应该知道,这两个方法会同时完成。
它们的编写顺序并不会影响它们的执行顺序
我们可以给异步操作做一个简单的定义
当一个操作开始执行后,主程序无需等待它的完成,可以继续向下执行。此时该操作可以跟主程序同就称之为 异步操作。 通常当操作完成时,会执行一个我们事先设定好的回调函数来做后续的处理。时(并发)执行。这种操作我们
我们常见的异步操作例如:
异步会带来什么问题?
比如我们现在有两个动画,需要按顺序来执行,也就是第一个结束,第二个才能开始
这个时候可能有点麻烦,传统的解决方法是通过回调:
这种方案显然不太好,如果有很多异步操作需要顺序执行,就会产生所谓的“回调地狱”
这种代码不管是写起来还是读起来都比较烦人。 我们来看下经过 Promise 改造后的样子(伪代码)
Promise 的使用及原理
要熟练 Promise 的的使用,你必须要先搞懂它解决问题的原理
贴一段实际的 Promise 代码,你来感受一下先:
上面的代码使用了 ES6 的 箭头函数,虽然大大简化了代码的写法,但对于初级程序猿来讲极不友好
读这种代码简直跟读金刚经差不多。我们把代码还原成ES5的样子
接下来,我们就按照费曼技巧来一步步的学习 Promise 是如何解决问题的
问题1作为一个异步函数,尤其像 ajax 这种网络请求,连我自己都不能确定函数的执行时间,Promise 是怎么知道第一个函数什么时候结束的? 然后再开始执行下一个?
Promise 并没有那么神奇,它并不能知道我们的函数什么时候结束,你注意到上面代码中的第3行了吗
在 ajax 请求结束执行回调的时候,我们调用了一个resolve()函数,这句代码非常的关键.
这其实就是在通知 Promise,当前这个函数结束啦,你可以开始执行下一个。 这时 Promise 就会去执行 then 里面的函数了。
问题2, 所以按照你的意思,如果我不调用这个方法,Promise 就不知道这个函数有没有结束,那么 then 里面的函数就不会执行,也就是说我的第二个请求就永远不会发送了呗?
Bingo!! 恭喜你已经学会了逻辑推理+抢答。
问题3可是这个resolve函数是从哪来的? 需要我自己定义吗? 从代码上看它好像是个参数,那又是谁传入函数中的?
你得先弄明白 Promise 的基本结构
我们把函数 1 和函数 2 都以参数形式传给了一个 Promise 对象,所以接下来函数 1 和 2 都会由这个 Promise 对象控制, 简单的说,函数 1 和函数 2 都会由 Promise 对象来执行。 所以在函数 1 执行时,参数也当然是由 Promise 对象传递进去的。
问题4, Promise 对象为啥要在执行第 1 个任务的时候,把这个resolve函数 传进来,有什么目的?
你说呢?
废屁,知道还用问你?
真是猪脑子,刚才不是已经说了吗? Promise 对象没办法知道我们的异步函数啥时候结束。那我来问你, 如果你去车站接人,可是你又不知道对方何时下车,你会咋办?
把我电话号码给他,快到了打我电话呗
没错,Promise 解决问题也采用了同样的思路。它传进来的 resolve 函数, 就好像一个对讲机,当我们的异步任务要结束时,通过对讲机 来通知 Promise 对象。也就是调用 resolve 方法
懂了,所以这个 resolve 函数,必须在异步任务的最后调用(例如 ajax 的回调方法),相当于告诉 Promise 对象,该任务结束,请开始下一个。
完全正确
问题5, 所以 Promise 也不过如此嘛,它没有带来什么功能上的革命性变化, 因为使用传统的回调嵌套的方式,同样可以完成效果。 说白了它就是编码方式上的改进??
基本是这样的,但 Promise 带来的编码方式以及异步编程思路上的进步是非常巨大的。
问题6, 那如果我有 ajaxA、ajaxB、ajaxC 三个异步任务,想按照先 A 后 B 再 C 的顺序执行,像这样写行吗?
不行
靠! 我还没说呢!
那你说
如果我这样写呢?
上面的这种写法是不对的。 Promise 的中文含义是“承诺”,则意味着,每一个 Pormise 对象,代表一次承诺
而每一次承诺,只能保证一个任务的顺序,也就是说
new Promise(A).then(B); 这句话表示, 只能保证 A 和 B 的顺序。
一旦 A 执行完,B 开始后,这次承诺也就兑现了,Promise 对象也就失效了
那如果还有 C 呢? 我们就必须在函数 B 中,重新创建新的 Promise 对象,来完成下一个承诺,具体的写法就像这样:
问题7, 懂了,那 Promise 还有什么其它强大的功能吗?
有啊,例如: 如果我有 A , B , C 三个异步任务,ABC 同时开始执行
当A,B,C三个任务全部都结束时,执任务 D,传统方法实现起来就比较复杂,Promise 就非常简单,就像这样:
问题8, 那如果我希望A,B,C其中任意一个任务完成,就马上开始任务 D,该怎么做?











评论