回调方法
优点:方便
缺点:业务复杂容易写成回调地狱,可读性较差,维护蛋疼
function callbackfn(num,callback) {
console.log('callbackfn')
setTimeout(() => {
console.log(num);
typeof callback == "function" && callback((++num));
}, 1000);
}
callbackfn(1,function (num) {
callbackfn(num,function (num) {
callbackfn(num,function (num) {
callbackfn(num,function (num) {
console.log('end')
})
})
})
})
Promise
优点:避免了回调地狱的写法,提供了一种回调函数的改进方案,单独看起来更加简洁
缺点:代码冗余,原来的任务被Promise包装,不管什么操作,一眼看上去都是一堆then(),状态一旦决定无法改变。
function promiseFn(num) {
return new Promise((resolve, reject)=>{
setTimeout(() => {
resolve(num)
}, 1000);
})
}
promiseFn(1).then((num)=>{
console.log('then')
console.log(num)
return promiseFn(++num)
}).then(num => {
console.log('then')
console.log(num)
return promiseFn(++num)
}).then(num => {
console.log('end')
})
Promise.all([promiseFn(1),promiseFn(2),promiseFn(3),promiseFn(4)]).then(results=>{
console.log('Promise.all');
console.log(results);
})
generator + co
优点:用同步的方式写异步操作,异步操作重的错误也容易被捕获到
缺点:需要额外调用执行器,yield 语义不清晰,yield 后面必须接受一个 Thunk 函数或 Promise 对象
function* generatorFn(){
let result = yield [
(yield promiseFn(1)),
(yield promiseFn(2)),
];
console.log("co");
console.log(result);
let pAResult = yield Promise.all([promiseFn(1),promiseFn(2)]);
console.log("co-promise.all");
console.log(pAResult);
}
co(generatorFn);
async / await
优点:是 generator 的一个语法糖,配合 Promise.all 可以实现并发请求,更好的语义,更简洁的语法,简直没理由不用他
缺点:兼容性问题,如果使用要引入 Babel 或者 引入regenerator runtime
async function anyncFn() {
console.log("anync");
let result1 = await promiseFn(1);
console.log(result1);
let result2 = await promiseFn(2);
console.log(result2);
let result3 = await promiseFn(3);
console.log(result3);
let result4 = await promiseFn(4);
console.log(result4);
}
async function anyncFn2() {
let result1 = await Promise.all([promiseFn(1),promiseFn(2),promiseFn(3),promiseFn(4)]);
console.log("anync-Promise.all");
console.log(result1);
}
anyncFn();
anyncFn2();