Javascript处理异步的三种方式

2018-11-25  本文已影响11人  西麦smile

callback

function ajax(fn) {
    setTimeout(() => {
        console.log('你好')
        fn()
    }, 1000)
}

// callback 回调地狱
ajax(() => {
    ajax(() => {
        ajax(() => {
            console.log('执行结束3')
        })
        console.log('执行结束2')
    })
    console.log('执行结束1')
})

执行结果:

你好
执行结束1
你好
执行结束2
你好
执行结束3

Promise

function delay(word) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('hello: ' + word)
        }, 1000)
    })
}

delay('name1')
    .then((word) => {
        console.log(word)   // hello name1
        return delay('name2')
    })
    .then((word) => {
        console.log(word)   // hello name2
        return delay('name3')
    })
    .then((word) => {
        console.log(word)   // hello name3
    })

执行结果:

hello: name1
hello: name2
hello: name3

async/await

function delay(word1) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('hello: ' + word1)
        }, 1000);
    })
}

// async + await 一起使用
// await 必须在 async 内部使用
// await 等待异步执行结束,这样看起来就像同步的形式
// await 就是等待的意思
async function start() {
    // 等待 delay('孙悟空') 结束
    const word1 = await delay('孙悟空')
    console.log(word1)
    // 等待 delay('猪八戒') 结束
    const word2 = await delay('猪八戒')
    console.log(word2)
    // 等待 delay1('沙悟净') 结束
    const word3 = await delay('沙悟净')
    console.log(word3)
}
start()

输出结果:

hello: 孙悟空
hello: 猪八戒
hello: 沙悟净

async/await 简介

async 函数实际上是 Generator 函数的语法糖,表示内部有异步操作

async 函数返回一个 Promise 对象,可以使用 then 添加回调函数,如下代码所示:

async function delay() {
    return 'hello world'
}

delay().then((value) => {
    console.log(value)  // hello world
})

await 命令后面是一个 Promise 对象,如果不是,会被转化为一个立即 resolve 的 Promise 对象,如下代码所示:

async function delay() {
    return await 123
}

delay().then(value => {
    console.log(value)  // 123
})

await 后面的 Promise 如果变成 reject 状态,reject 会被 catch() 的回调捕捉到,如下代码所示:

注意: 即使 await 前面没有 return,reject 的参数也一样可以传入catch() 中,即使加上 return 结果也是一样的。

async function delay() {
    await Promise.reject('error')
}

delay().then(value => {
    console.log(value)
}).catch(error => {
    console.log(error)  // error
})

如果 async 函数中的 await 的异步处理操作发生错误,那么 async 返回的 Promise 对象也一样被 reject,如下代码所示:

async function delay() {
    await new Promise((resolve, reject) => {
        reject('error')
    })
}

delay()
    .then((value) => console.log(value))
    .catch((error) => console.log(error))   // error

由于 await 后面是 Promise 对象,因此有可能会 rejeceted,因此最好把 await 放在 try...catch 代码块中,如下代码所示:

async function delay() {
    await maybeReturnAPromise()
    .catch((error) => {
        console.log(error)
    })
}

function maybeReturnAPromise() {
    return Promise.reject('error')
}

delay()
    .then(value => console.log(value))  // error
    .catch(error => console.log(error)) // undefined

多个 await,如果不存在继发关系,则让他们同时触发,如下代码所示:

// 方法 1
let [foo, bar] = Promise.all([getFoo(), getBar()])

// 方法 2
let fooPromise = getFoo()
let barPromise = getBar()
let foo = await fooPromise
let bar = await barPromise

from:2018-06-01 11:20:03

上一篇 下一篇

猜你喜欢

热点阅读