# 异步任务串行执行的方法

异步任务我们经常需要同步执行,但有时也需要串行执行,那如果要串行执行,有哪些实现方式呢?

# 第一种方法:通过函数调用的方式

let taskA = setTimeout(() => {
  console.log('A');
  taskB('A');
}, 100);
let taskB = (data) => {
  console.log('B');
  taskC(data+'B');
};
let taskC = (data) => {
  console.log(data+'C');
};
1
2
3
4
5
6
7
8
9
10
11

这种方式应该是最简单也最原始实现串行执行的方式;

# 第二种方式:通过实现next方法

即通过写一个叫next的方法来实现数据的传递,以实现串行执行,代码如下:

function waterfall(tasks,callback){
  let next = function(data){
    if(tasks.length === 0){
      callback(null, data);
      return ;
    }
    let fn = tasks.shift();
    fn(next, data)
  }
  next('');
}
waterfall([
  function(cb,data){
    cb(data+' 1');
  },
  function(cb,data){
    cb(data+' 2');
  },
  function(cb,data){
    cb(data+' done')
  }
], function(err, result){
  console.log('result',result)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

next函数会自调用,相当于递归调用自己,从而实现串行执行。

# 第三种方法:借助promise.then来实现串行执行

promise.then不多说,看代码:

let taskA = (data) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('task A: '+data);
    resolve(data+' a');
  });
 })
 let taskB = (data) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('task B: '+data);
    resolve(data+' b');
  });
 })
 let taskC = (data) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('task C: '+data);
    resolve(data+' c');
  });
 })
 function start() {
    console.log('start');
    taskA('go').then(taskB).then(taskC);
 }
 start();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 第四种方法:使用es6的async&await

比较简单,其实和promise的实现方法类似,就是使用了async&await语法糖而已,附上代码:

async function f1(){
  let d1 = await new Promise(resolve => {
    setTimeout(()=>{
      resolve('t1');
    }, 10);
  })
  let d2 = await new Promise(resolve => {
    setTimeout(()=>{
      resolve(d1 +'t2');
    }, 10);
  });
  console.log(d1,d2)
}
f1();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 第五种方式:通过reduce实现串行执行

代码如下:

let createP = (data) => (predata) => new Promise((resolve,reject)=>{
    setTimeout(() => {
      resolve(predata + data);
    });
  }, 0);
let mytasks = [
  createP(' p1'),
  createP(' p2'),
  createP(' p3'),
  createP(' p4')
];
let result = mytasks.reduce((acc, item) => acc.then((predata) => item(predata)), Promise.resolve('start')); 
result.then(res => {
  console.log('result',res)
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
最后更新时间: 11/7/2020, 4:54:46 PM