一般而言,回调函数的形式为callback(err, res),即第一个参数是错误,第二个参数是所得的结果,我们遵从这个习惯
当然, 一般err和res总有一个是undefined,因为函数的结果要不就是正确执行,要不就是失败,不可能两者同时存在
1. 接受异步函数的返回值与异常处理
同步函数的写法
var func = function() {
try {
var res = funcSync();
var execute = doSomething(res);
return execute;
} catch(err) {
var execute = handle(err);
return execute;
}
}
异步函数的写法
var func = function(callback) {
funcAsyn(function(err, para) {
if(err) {
callback(handle(err), undefined);
} else {
var execute = doSomething(para);
callback(err, execute);
}
})
}
注意到,无论结果是什么,funcAsyn的回调函数都要以func传入的callback函数结束
其中对应关系如下表
同步函数 | 异步函数 |
---|---|
函数名 | funcSync |
返回值 | return |
异常 | throw |
2. 多个函数顺序执行
同步函数的写法
func3();
func2();
func1();
异步函数的写法
var next = function(funcList) {
var i = 0;
return function(para) {
if(i!=funcList.length) {
funcList[i++](para);
}
}
}([func3, func2, func1])
需要注意的是,每一个依次执行的异步函数最后,都需要加上一句next()
例如
var func1 = function() {
setTimeout(() => {
console.log(1);
next(); //需要加上这一句
}, 100);
}
3. 得到多个函数的返回值
以得到三个函数返回值的和为例
同步函数的写法
var res = func1Sync() + func2Sync() + func3Sync();
异步函数的写法
var aggregrate = function(funcList, callback) {
var finish = 0;
var result = [];
var error = [];
var getResult = function(index) {
return function(err, res) {
result[index] = res;
if(err) {
error.push(err);
} else {
result[index] = res;
}
if(++finish == funcList.length) {
if(error.length == 0) {
callback(undefined, result);
} else {
callback(error, undefined);
}
}
};
};
for(let i=0; i!=funcList.length; ++i) {
funcList[i](getResult(i));
//getResult的作用是把函数处理的结果记录在一个数组中
}
};
调用这个函数的一个例子如下
var funcAsyn1 = function(callback) {
setTimeout(() => {
callback(undefined, 1);
}, 100);
};
var funcAsyn2 = function(callback) {
setTimeout(() => {
callback(undefined, 2);
}, 200);
};
var funcAsyn3 = function(callback) {
setTimeout(() => {
callback(undefined, 3);
}, 150);
};
var funcList = [funcAsyn1, funcAsyn2, funcAsyn3];
var sum = function(err, result) {
var sum = 0;
for(let i=0; i!=result.length; ++i) {
sum += result[i];
}
console.log(sum);
};
var res = aggregrate([funcAsyn1, funcAsyn2, funcAsyn3], sum);