翼度科技»论坛 编程开发 JavaScript 查看内容

第125篇: 期约Promise基本特性

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记
 
1.非重入期约

1.1.可重入代码(百度百科)

先来了解一个概念

可重入代码(Reentry code)也叫纯代码(Pure code)是一种允许多个进程同时访问的代码。
为了使各进程所执行的代码完全相同,故不允许任何进程对其进行修改。
程序在运行过程中可以被打断,并由开始处再次执行,并且在合理的范围内(多次重入,而不造成堆栈溢出等其他问题),
程序可以在被打断处继续执行,且执行结果不受影响。
                                            ----来自百度百科
 
1.2.非重入期约
非重入期约方法 期约进入 落定(解决/拒绝)状态时,与该状态相关的处理程序不会立即执行 ,
处理程序后的 同步代码 会在其之前 先执行 ,该特性称为非重入
当期约进入落定状态时,与该状态相关的处理程序仅仅会被排期,而非立即执行。
跟在添加这个处 理程序的代码之后的同步代码一定会在处理程序之前先执行。
即使期约一开始就是与附加处理程序关联 的状态,执行顺序也是这样的。
这个特性由 JavaScript 运行时保证,被称为“非重入”(non-reentrancy) 特性。
 
  1. <strong>let promise = new Promise(() => {
  2.     console.log("5")
  3. })
  4. // 创建一个期约并将解决函数保存在一个局部变量中
  5. let p = new Promise((resolve) => {
  6.     synchronousResolve = function () {
  7.         console.log('1');
  8.         resolve();
  9.         console.log('2');
  10.     };
  11.     synchronousResolve();
  12. });
  13. p.then(() => console.log('4'));
  14. console.log('3');</strong>
复制代码
 

看到了吗,这里4依旧被放在了最后输出
这说明在这个例子中,即使期约状态变化发生在添加处理程序之后,处理程序也会等到运行的消息队列让 它出列时才会执行。
 
 
 
2.邻近处理程序的执行顺序

如果给期约添加了多个处理程序,当期约状态变化时,相关处理程序会按照添加它们的顺序依次执行
  1. <strong>let p1 = Promise.resolve();
  2. p1.then(() => setTimeout(console.log, 0, 1));
  3. p1.then(() => setTimeout(console.log, 0, 2));
  4. p1.then(() => setTimeout(console.log, 0, 3));
  5. p1.then(() => setTimeout(console.log, 0, 4)); </strong>
复制代码

 
 
 
 
3.期约连锁

把期约逐个地串联起来是一种非常有用的编程模式。
之所以可以这样做,是因为每个期约实例的方 法(then()、catch()和 finally())都会返回一个新的期约对象,
而这个新期约又有自己的实例方,这样连缀方法调用就可以构成所谓的“期约连锁”
你应该能想象到,这就是一长串then(),( then()、catch()和 finally()都行 )
  1. <strong>let p = new Promise((resolve, reject) => {
  2.     resolve();
  3. });
  4. p.then(() => console.log('1'))
  5.     .then(() => console.log('2'))
  6.     .then(() => console.log('3'))
  7.     .then(() => console.log('4'));</strong>
复制代码
 

 
 
 
4.期约合成

这肯定是个将多个期约合成为一个的某个特性(废话)
Promise 类提供两个将多个期约实例组合成一个期约的静态方法:Promise.all()和 Promise.race()。
而合成后期约的行为取决于内部期约的行为。

4.1.Promise.all()
特性一:合成的期约只会在每个包含的期约都解决之后才解决
特性二:如果至少有一个包含的期约待定,则合成的期约也会待定。
如果有一个包含的期约拒绝,则合成的 期约也会拒绝
  1. <strong>let p1 = Promise.all([
  2.     Promise.resolve(),
  3.     new Promise((resolve, reject) => {
  4.         resolve();
  5.     })
  6. ]);
  7. console.log("I'm p1");
  8. console.log(p1);
  9. // 一次拒绝会导致最终期约拒绝
  10. let p2 = Promise.all([
  11.     Promise.resolve(),
  12.     Promise.reject(),
  13.     Promise.resolve()
  14. ]);
  15. console.log("I'm p2");
  16. console.log(p2);
  17. let p3 = Promise.all([
  18.     Promise.resolve(),
  19.     new Promise(() => {}),
  20.     Promise.resolve()
  21. ]);
  22. console.log("I'm p3");
  23. console.log(p3);</strong>
复制代码
 

 
 
 
4.2.Promise.race()

Promise.race()不会对解决或拒绝的期约区别对待。
无论是解决还是拒绝,只要是第一个落定的 期约,Promise.race()就会包装其解决值或拒绝理由并返回新期约
  1. <strong>let p1 = Promise.race([
  2.     Promise.resolve(),
  3.     new Promise((resolve, reject) => {
  4.         resolve();
  5.     })
  6. ]);
  7. console.log("I'm p1");
  8. console.log(p1);
  9. // 一次拒绝会导致最终期约拒绝
  10. let p2 = Promise.race([
  11.     Promise.resolve(),
  12.     Promise.reject(),
  13.     Promise.resolve()
  14. ]);
  15. console.log("I'm p2");
  16. console.log(p2);
  17. let p3 = Promise.race([
  18.     Promise.resolve(),
  19.     new Promise(() => {}),
  20.     Promise.resolve()
  21. ]);
  22. console.log("I'm p3");
  23. console.log(p3);</strong>
复制代码
 

 
 
 
5.课后练习
 
1.什么是promise期约连锁?
  答:Promise期约连锁调用是使用Promise的一种技术,它可以让你把多个Promise以链式的方式组合起来,每个Promise的结果作为下一个Promise的输入。
这样可以把复杂的操作分解成一系列简单的操作,以便更容易理解和管理。
 
2.如何解释Promise的的非重入特性?
  答:非重入期约方法 期约进入 落定(解决/拒绝)状态时,与该状态相关的处理程序不会立即执行 ,
 
处理程序后的 同步代码 会在其之前 先执行 ,该特性称为非重入
 

来源:https://www.cnblogs.com/FatTiger4399/p/17177064.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具