Promise的链式调用什么原理?

大家都知道jQuery的链式调用是return this的妙用,那么Promise的呢?比如

function start() {  
    return new Promise((resolve, reject) => {  
      resolve('start');  
    });  
  }  
    
  start()  
    .then(data => {  
      // promise start  
      console.log('result of start: ', data);  
      return Promise.resolve(1); // p1  
    })  
    .then(data => {  
      // promise p1  
      console.log('result of p1: ', data);  
      return Promise.reject(2); // p2  
    })  
    .then(data => {  
      // promise p2  
      console.log('result of p2: ', data);  
      return Promise.resolve(3); // p3  
    })  
    .catch(ex => {  
      // promise p3  
      console.log('ex: ', ex);  
      return Promise.resolve(4); // p4  
    })  
    .then(data => {  
      // promise p4  
      console.log('result of p4: ', data);  
    });  

result of start: start
result of p1: 1
ex: 2
result of p4: 4

第三步,reject的还被下一步的then忽略掉了,这种链式调用是什么原理?怎么实现的?

阅读 4.5k
4 个回答

你这个类比不合适。

第三步,reject 的还被下一步的 then 忽略掉了

正确的说法是:then调用并没有被忽略,而是 then 里面的回调被忽略执行了。

你试试下面这段代码就知道了:

Promise.reject(1).then(console.log('foo bar'));

依然输出了 foo bar,可见 then 函数其实已经执行了。

如果写成:

Promise.reject(1).then(() => console.log('foo bar'));

就不会输出了。只是说,then 函数中传入了一个回调函数,当 Promise 的状态为 rejected 时,这个回调函数没有被执行,并是 then 函数没有被执行。

我们做个合适的类比。以下 jQuery 链式调用:

$('#a_id_selector')
  .addClass('someclassname')
  .click(() => console.log('foo bar'))
  .prop('type', 'text');

我们运行这段代码,也没有输出 foo bar,但是我们不能说 click 函数被忽略掉了。

这样你就明白了吧。

因为啊,每个then都返回一个新的promise,每个then都返回一个新的promise,每个then都返回一个新的promise。
返回的新的promsie会在上一个promise的状态变更改时候开始执行,以此类推,每次返回的新的promise被挂在上一个promise上,就此串成了一串

.then返回了一个新的promise对象 也就是说 一片的then其实除了第一个是start的 其他的都不是

链式调用的实现都很简单,在函数中返回值是这个对象自身就可以。

Promise对象只能从Pending转向resolved或者从Pending转向rejected,且状态转换完毕后就不会更改,也不会响应后面的resolve和reject。这是Promise的规范定义的

Promise的实现有很多,本站就有很多文章有相关的阐述,可以去参看一下

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题