Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript深入系列之Promise #9

Open
archerU opened this issue May 22, 2018 · 0 comments
Open

JavaScript深入系列之Promise #9

archerU opened this issue May 22, 2018 · 0 comments

Comments

@archerU
Copy link
Owner

archerU commented May 22, 2018

异步编程中通过回调表达程序异步和管理并发的两个主要缺陷:缺乏顺序性和可信任性。

Promise

Promise 是一种封装和组合未来值的易于复用的机制,用于解决异步编程中可信任性问题。

顺序的大脑

// A 
setTimeout(function() {
    // C
},1000);
// B

// 交换x和y,通过临时变量z
z = x;
x = y;
y = z;

思考以上两个伪代码片段的执行顺序。第一个我们大脑这么描述:执行 A,设定延时 1000ms,然后执行 B,然后 1000ms 后执行 C。
第二个我们大脑这么描述: z=x 执行完毕后,然后执行 x=y,最后执行 y=z。第二个描述,我们的大脑思考方式是一步一步的,但是第一个不是。

回调

缺乏顺序性,回调函数会导致代码变得更加难以理解(跳来跳去查看流程)、追踪(跟踪异步流困难)、调试维护

doA(function() {
    doB();
    
    doC(function() {
        doD(); 
    });
    
    doE();
});
doF();

如果 doA,doC 是异步执行的,伪代码的执行顺序是这样的:

  • doA()
  • doF()
  • doB()
  • doC()
  • doE()
  • doD()

如果 doA,doC 是同步执行的,伪代码的执行顺序是这样的:

  • doA()
  • doB()
  • doC()
  • doD()
  • doE()
  • doF()

回调导致我们跟踪异步流非常困难。同步或异步行为引起的不确定性导致bug追踪困难。并且嵌套在异步流中的代码通常无法复用。一旦控制流程变化,回调中的代码也会导致很难以维护和更新。

信任

回调最大的问题是控制反转导致的信任问题。因为回调暗中把控制权交给第三方(通常是不受你控制的第三方工具!)来调用你代码中的 continuation 。这种控制转移导致一系列麻烦的信任问题。

// A
ajax("..",function(..) {
    // C 
});
// B

这样的代码通常不会有问题。如果 ajax(..) 不是你编写的代码,而是第三方的提供的工具,那就相当于把自己程序一部分的执行控制权交给了第三方,这就会导致一系列信任问题。

Promise 信任问题

调用回调过早

promise 提供给 then(..) 的回调总是会被异步调用。

调用回调过晚

promise 决议后,所有通过 then(..) 注册的回调都会在下一个异步时机点上依次被立即调用。

回调未调用

promise 在决议时总是会调用一个完成回调或一个拒绝回调。

调用回调次数过少或过多

promise 只能被决议一次。

未能传递参数/环境值

promise 至多只能有一个决议值(完成或拒绝)。如果没有任何值显示决议,那么这个值就是 undefined。

吞掉错误或异常

promise 会把出错消息传给拒绝回调。

Promise 模式

Pormise.all([..])

promise.all([..]) 返回的主 promise 在且仅在所有的成员 promise 都完成后才会完成。如果这些 promise 中有任何一个被拒绝的话,主 Promise.all([..]) promise 就会立即被拒绝,并丢弃来自其他所有 promise 的全部结果。

Promise.race([..])

promise.race([..]) 一旦有任何一个 Promise 决议为完成,Promise.race([..]) 就会完成,一旦有任何一个 Promise 决议为拒绝,它就会拒绝。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant