学了ES6,还不会Promise的链式调用?🧐

605 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

本文主要讲解promise的链式调用的方法及其最终方案

应用场景

假如开发有个需求是先要请求到第一个数据,然后根据第一个数据再去请求第二个数据,再根据第二个数据去请求第三个数据...一直到最后得到真正想要的数据,我最初的做法是

setTimeout(() => {
  //这里用定时器来代替发请求
  //data假设为后台来的数据
  let data1 = 1;
  console.log(data1);
  setTimeout(() => {
    let data2 = 2 + data1;
    console.log(data2);
    setTimeout(() => {
      let data3 = 3 + data2;
      console.log(data3);
      setTimeout(() => {
        let data4 = 4 + data3;
        console.log(data4);
      }, 100);
    }, 100);
  }, 100);
}, 100);

显然代码是没有任何问题的,但是如果在每次都在获取数据过来还要进行数据的处理呢?那这种代码就变得晦涩难懂且难以维护,搞不好维护你代码的人****。于是这种情况下,Promise就是一个很好的选择。

以上代码就会变成这样的形式

//链式调用
p.then(value=>{

},reason=>{

}).then(value=>{

},reason=>{
  
})
...

接下来我们就一起来学习Promise的链式调用吧

实现方法

原理:每次调用then方法都return一个promise对象,因为promise带有then方法,这样就可以在上一个then后面再调用then方法。

const p = new Promise((resolve, reject) => {
    let data1 = "data1"; //后台获取到data1
    console.log(data1);
    resolve(data1);
  });
  p.then((res) => {
    return new Promise((resolve, reject) => {
      let data2 = res+"data2"; //后台获取到data2
      console.log(data2);
      resolve(data2);
    });
  }).then((res) => {
    console.log(res);
  });
//  data1
//  data1data2
//  data1data2

看到这里,就会有人问了,这个代码也好看不到哪里去啊,怎么就是一个好的选择了,先等下,还没出最终答案呢

刚刚我们说到,链式调用的原理是每次都在then方法里面返回一个promise对象,通过资料查询,我们会发现Promise的resolve方法返回的就是一个Promise对象

image.png 于是刚刚的代码就可以改成下面的形式

const p = new Promise((resolve, reject) => {
  let data1 = "data1"; //后台获取到data1
  console.log(data1);
  resolve(data1);
});
p.then((res) => {
  let data2 = res + "data2"; //后台获取到data2
  console.log(data2);
  return Promise.resolve(data2);
}).then((res) => {
  console.log(res);
});
//  data1
//  data1data2
//  data1data2

现在看起来是不是舒服很多,但是其实刚刚搜索resolve方法的时候你还会发现,then方法其实返回的也是一个Promise对象

image.png 这样子,最后方案就出来了

const p = new Promise((resolve, reject) => {
  let data1 = "data1"; //后台获取到data1
  console.log(data1);
  resolve(data1);
});
p.then((res) => {
  let data2 = res + "data2"; //后台获取到data2
  console.log(data2);
  return data2;
}).then((res) => {
  console.log(res);
});
//  data1
//  data1data2
//  data1data2

万物皆有裂痕,是光进来的地方

参考来源

  • 尚硅谷es6-11视频