Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

处理js的异步逻辑 #8

Open
chiwent opened this issue Nov 16, 2018 · 1 comment
Open

处理js的异步逻辑 #8

chiwent opened this issue Nov 16, 2018 · 1 comment

Comments

@chiwent
Copy link
Owner

chiwent commented Nov 16, 2018

优雅地处理js的异步

处理串行异步逻辑

    在很多业务逻辑中,我们需要串行处理多个异步的操作,在早期的方法中,我们可以使用Promise.all来处理,一个任务列表按顺序依次执行(网上一些文章说是并行执行?? 参考这里的讨论:cnode),当有其中一个rejected,返回的就是rejected。如果是用race,假如队列中有任意一项出错,整个队列都不会有输出结果,虽然说结果是一样的,但是race的执行时间取决于执行最快的那个 promise,而all的执行时间取决于执行最慢的那个 promise。假如我们单纯用promise来处理逻辑,其链式调用的格式比较粗糙。当我们引用async/await时,我们不仅可以轻松实现不同的逻辑(改动的内容较小),并且还可以让代码看起来更像是同步的

var arr = [100, 300, 400, 200]

function newError() {
    return new Promise((resolve, reject) => {
        throw new Error('Throw Error')
    })
}

function setTime(time){
  return new Promise((resolve, reject)=>{
    if (time <= 300 && resolve) {
        setTimeout(()=>resolve(time),time);
    } else if (time > 300 && reject) {
        reject('Error in', time)
    }
  })
}

// Promise.all只要有一个失败,就会rejected
Promise.all([setTime(300), setTime(400), setTime(100)]).then(val => {
    console.log(val)
})

// Promise.race一旦遇到错误,就会退出
Promise.race([setTime(200), setTime(100), setTime(400)]).then(val => {
    console.log(val)
})

// 通过then链式调用的方法,一旦某个任务出现错误,那么最后的状态就为rejected,后面的任务不执行(前面正确的依旧正常输出)
setTime(300).then(val => {
    console.log(val)
    return newError()
}).then(val => {
    console.log(val)
    return newError()
}).then(val => {
    console.log(val)
}).catch(err => {
    console.log(err)
})

// 我们可以将promise实例放到async/await的循环内处理,这样无论任意的promise是否出错,所有的promise都会执行
async function asyncPromise(arr, handler) {
    let result = []
    for (let i of arr) {
        let wait;
        try {
            wait = await handler(i)
        } catch (err) {
            console.log('catch Error')
        }
        result.push(wait) 
    } 
    return result;
}

asyncPromise(arr, setTime).then(val => {
    console.log(val)
})


// 使用async/await来封装promise任务队列有一个很灵活的地方,假如再for循环中有任意一个任务出错,那么我们可以再try/catch将其捕获,然后break跳出循环,这样,一旦中间出现了错误,就可以中途退出
async function asyncPromise(arr, handler) {
    let result = []
    for (let i of arr) {
        let wait;
        try {
            wait = await handler(i)
        } catch (err) {
            console.log('catch Error:', err)
            break
        }
        result.push(wait) 
    } 
    return result;
}

asyncPromise(arr, setTime).then(val => {
    console.log(val)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant