JavaScript 学习笔记 - 异步处理探索之路

167 阅读1分钟

回调方法

优点:方便
缺点:业务复杂容易写成回调地狱,可读性较差,维护蛋疼
 // callback 回调模式
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(),状态一旦决定无法改变。
// Promise
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 对象
//引入co模块
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
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();