异步处理

参考

以下代码会输出饿了,因为setTimeout是异步处理的,相当于人家刚吃就问人家吃饱了吗

let status = '饿了';

function eat() {
    setTimeout(() => {
        status = '吃饱了';
    }, 500);
}

eat();
console.log(status);

callback

以下代码会输出吃饱了,因为是在状态变成吃饱了之后才问的

let status = '饿了';

function eat(callback) {
    setTimeout(() => {
        status = '吃饱了';
        callback && callback();
    }, 500);
}

eat(() => {
    console.log(status);
});

如果这个人胃口比较大,需要吃三碗才能吃饱,代码如下

let status = '饿了';
let bowl = 0;

function eat(callback) {
    setTimeout(() => {
        bowl++;
        if (bowl >= 3) {
            status = '吃饱了';
        } else {
            status = '没吃饱';
        }
        callback && callback();
    }, 500);
}

eat(() => {
    console.log(status);
    if (status != '吃饱了') {
        eat(() => {
            console.log(status);
            if (status != '吃饱了') {
                eat(() => {
                    console.log(status);
                })
            }
        })
    }
});

可以发现使用回调的方式,如果碰到复杂的或者嵌套层数很多的情况,代码维护起来就很困难,这就是经典的回调地狱( callback hell )问题

promise

由于异步回调维护困难,所以es6引入了promise

let status = '饿了';
let bowl = 0;

function eat() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            bowl++;
            if (bowl >= 3) {
                status = '吃饱了';
            } else {
                status = '没吃饱';
            }
            if (Math.random() < 0.1) {
                reject(new Error("撑死了"));
            } else {
                resolve(status);
            }
        }, 500);
    });
}

eat().then((res) => {
    console.log(res);
    return eat();
}).then((res) => {
    console.log(res);
    return eat();
}).then((res) => {
    console.log(res);
}).catch(err => {
    console.log(err.message);
}).finally(() => {
    console.log("不管怎样,味道还是很不错的");
});

如果同时发起多个异步任务,可以使用Promise.all()解决异步并发问题

function eat(food) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("吃了" + food);
            return resolve({
                food: food,
                flag: Math.random()
            });
        }, 500);
    });
}

Promise.all([eat("肉包子"), eat("菜包子"), eat("小笼包")]).then((res) => {
    let winner = null;
    for (let o of res) {
        if (winner == null) {
            winner = o;
        } else if (o.flag > winner.flag) {
            winner = o;
        }
    }
    console.log(winner.food + "最好吃");
});

async/await

async/await可以让我们用同步的思维去编写异步代码

async是修饰function的关键字,async function其实是一个Promise的语法糖

const success = async function () {
    return 'success';
}
const fail = async function () {
    throw new Error('fail');
}

// async ƒ () { return 'success'; }
console.log(success);
// async ƒ () {return new Error('fail'); }
console.log(fail);
// Promise {<fulfilled>: 'success'}
console.log(success());
// Promise {<rejected>: Error: fail}
console.log(fail());

await是async functon中的一个关键字,用来阻止后面的代码立即执行,并且可以用同步的方法获取到Promise的执行结果

(async function () {
    let status = '饿了';

    await new Promise((resolve, reject) => {
        setTimeout(() => {
            status = '吃饱了';
            resolve();
        }, 500);
    });

    console.log(status);
}());

如果这个人胃口比较大,需要吃三碗才能吃饱,代码如下

let status = '饿了';
let bowl = 0;

function eat() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            bowl++;
            if (bowl >= 3) {
                status = '吃饱了';
            } else {
                status = '没吃饱';
            }
            if (Math.random() < 0.1) {
                reject(new Error("撑死了"));
            } else {
                resolve(status);
            }
        }, 500);
    });
}

(async function () {
    try {
        await eat();
        console.log(status);
        await eat();
        console.log(status);
        await eat();
        console.log(status);
    } catch (e) {
        console.log(e.message);
    } finally {
        console.log("不管怎样,味道还是很不错的");
    }
}());

results matching ""

    No results matching ""