# 异步任务串行执行的方法
异步任务我们经常需要同步执行,但有时也需要串行执行,那如果要串行执行,有哪些实现方式呢?
# 第一种方法:通过函数调用的方式
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
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
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
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
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15