专栏名称: freeCodeCamp
FreeCodeCamp.cn官方公众号
目录
相关文章推荐
51好读  ›  专栏  ›  freeCodeCamp

当我们说 Promise ,我们在说什么?(刨根向)

freeCodeCamp  · 公众号  ·  · 2018-01-02 17:49

正文

当我要组织文章内容的时候,我感到十分的吃力。

这是源于一个困惑:我们现在是否还需要探讨什么是 Promise

我们很容易就能 “使用” Promise ,已经有很多优秀的模块实现了不同标准的 Promise 。 而随着ES6原生 Promise 的落实,我们更容易写出 Promise 风格的异步代码。

// ES6 下的原生Promise
var httpGet = (url) => {  return new Promise( (resolved,rejected)=>{
    request.get(url,(err,res)=>{      if(!err){
        resolved(res);
      }else{
        rejected(err);
      }
    });
  });
}

httpGet('http://abc.com').then(...);

但是,治学这东西,知其然,还要知其所以然。

尤其是现在很多声音还存在对 Promise 的曲解的情况下。

那么,Promise到底是什么东西?

有一种说法是用了 Promise 就不需要callback的写法了,实际上是不是这样,我们看一段代码

func(arg ,(err,ret)=>{  //pass
});

func(arg).then( (err,ret)=>{  //pass
});

实际上只是callback写的位置不一样而已,并没有什么实际的改变。

是不是这样呢?我们层层深入地理解一下 Promise 到底是什么。

对于上面这个问题, Promise 是不是只是把callback换个地方写呢?

我从《深入浅出Nodejs》 4.3.2 中的一段话收到了启发

上面的异步调用中,必须严谨地设置目标。那么是否有一种先执行异步调用,延迟传递处理的方式呢?

说的就是传统的callback写法,必须在异步调用的时候,明确地声明回调处理的逻辑。

httpGet('/api',{
  success:onSuccess,
  error:onError
});

就是说,你必须明确指明了异步调用结束时的各种回调,然后才会执行异步操作

(声明异步操作)---> (注册回调) ---> (执行异步操作)

反过来看看 Promise 是不是就不一样呢?先看一段代码

var p = httpGet('/api');

p.then(onSuccess , onError);

你猜到底在哪一步发起了http请求?

正如你猜测的一样,在 p 初始化的时候,这个异步操作就执行了。 所以对于 Promise 来说,流程是这样的

(声明异步操作)---> (执行异步操作) ---> (注册回调)

>原来真的存在一种方法,先执行异步调用,延迟传递处理的方式。这就是 Promise 与传统callback一个很显著的区别。

状态机

如果 Promise 只是对callback在逻辑顺序及书写方式上面的一点改动的话,

那你就小看它了。

有没有想过,为什么 Promise 能先执行异步操作,再指明回调逻辑呢?下面这段代码又会如何?

var p = httpGet('/api');// do something

p.then(onSuccess , onError);// do something

p.then(onSuccess , onError);

请问,第二个 then 是否正常执行 ?

Promise 下的状态

Promise 定义了其内部的几个状态

  • pending

  • resolved (fullfilled)

  • rejected

Promise 初始化后 内部状态为 pending ,然后开始执行异步操作, 当异步操作完成,内部状态转换为 resolved rejected (失败时)。

一旦状态改变,就会被固化,不会再改变。

所以就很好解释,一个状态已经确定的 Promise ,无论你调动多少次 then ,它都会返回正确且唯一的结果,因为 Promise 的结果,是完全依赖它自己的内部状态。

这个时候我们有必要说一下 then 方法到底做了什么?

不去深入探究的话,你大概会认为 then 只是注册了一系列回调函数。

其实 then 除了注册回调函数,还会检查 Promise 状态,只要不是 pending 状态,就回调用相应状态的回调。







请到「今天看啥」查看全文