Promise链式调用与升级版

什么是链式调用?

对于用过jq的人来说这个概念很好理解,例如:

$('text').setStyle('color', 'red').show();

其中调用过setStyle方法后可以立即再调用show方法。这要的调用方式就是链式调用。

链式调用是如何实现的?

一般的链式调用完方法后,return this返回当前调用方法的对象就能实现链式调用。

首先,我们先来看看一般函数的调用方式

(1)先创建一个简单的类

//创建一个bird类
function Bird(name) {
 this.name=name;
 this.run=function() {
    console.log(name, "start run;");
 }
 this.stopRun=function() {
    console.log(name, "start run;");
 }
 this.sing=function() {
    console.log(name, "start sing;");
 }
 this.stopSing=function() {
    console.log(name, "start stopSing;");
 }
}

(2)使用方式:一般的调用方式

var bird=new Bird("测试"); 
bird.run();
bird.sing();
bird.stopSing();
bird.stopRun();

(3)结果

测试 start run;
测试 start sing;
测试 start stopSing;
测试 start run;

总结,该种方式有一个弊端就是:多次重复使用一个对象变量

然后,我们再来看看将上述改成链式调用的格式

(1)在创建的简单类中加上return this,如下

//创建一个bird类
function Bird(name) {
 this.name=name;
 this.run=function() {
    console.log(name, "start run;");
    return this;// return this返回当前调用方法的对象。
 }
 this.stopRun=function() {
    console.log(name, "start run;");
    return this;// return this返回当前调用方法的对象。
 }
 this.sing=function() {
    console.log(name, "start sing;");
    return this;// return this返回当前调用方法的对象。
 }
 this.stopSing=function() {
    console.log(name, "start stopSing;");
    return this;// return this返回当前调用方法的对象。
 }
}

(2)使用链式调用(连缀的方式)

var bird=new Bird("测试");
bird.run().sing().stopSing().stopRun();

(3)结果

测试 start run;
测试 start sing;
测试 start stopSing;
测试 start run;

总结此种方式的调用结果与一般的调用方式产生的结果一样,优点是:链式调用这种风格有助于简化代码的编写工作,让代码更加简洁、易读,同时也避免多次重复使用一个对象变量

Promise链式调用

什么是promise的链式调用呢

// 省市区
function printProvince() {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
      console.log('省');
      resolve();
    }, 100);
  });
}
function printCity() {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
      console.log('市');
      resolve();
    }, 100);
  });
}
function printArea() {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
      console.log('区');
      resolve();
    }, 100);
  });
}
printProvince().then(() => {
  return printCity();
}).then(() => {
  return printArea();
}).then(() => {
  console.log('打印完成');
});

结果




打印完成

Promise链式调用升级版

上边的链式调用已经简化了一些代码,逻辑也比较清晰,但是在遇见大数据量的处理时then就要写好长好长,有没有好的方法能实现代码动态控制自动完成的情况呢?

const createPromise = (name) => () => {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
      console.log(name);
      resolve();
    }, 100);
  });
}
const phones = ['华为', '小米', 'OPPO', '金立', '荣耀'];
const allP = [];
phones.forEach((phone) => {
  allP.push(createPromise(phone));
});
allP.reduce((prev, next) => prev.then(() => next()), Promise.resolve()).then(() => {
 console.log('执行完成');
});

执行结果:

华为
小米
OPPO
金立
荣耀
执行完成

这样就可以动态生产一个链式调用的过程了。相比于上边的手动写链式调用要代码量少好多。

总结

有人说这个和Promise.all有点像,但是也有区别。

(1)链式调用是串行调用,一个promise执行完成后才调用下一个promise;Promise.all是并行执行,其中的promise没有先后顺序,有计算机随机调用。

(2)链式调用执行时间会长,但是占用的计算机资源少;Promise.all 执行时间相比链式调用短,但是占用的计算机资源多。

上一篇:linux之getopt 函数


下一篇:向VPP中添加新结点,改变数据走向