您当前的位置: 首页 > 

【03】

暂无认证

  • 1浏览

    0关注

    196博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

实现异步任务同步处理结果

【03】 发布时间:2020-07-17 10:33:56 ,浏览量:1

模拟两个成功的请求(不考虑reject)
 function request1() {
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("数据1")
            },1000)
        })
    }
function request2() {
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("数据2")
            },1000)
        })
    }
实现同步请求方法1(回调)
function fn1() {
    console.time("fn1")
    let data1 = null
    let data2 = null
    request1().then(d1=>{
        data1 = d1
        request2().then(d2=>{
            data2 = d2
            handel()
        })
    })
    function handel() {
        console.log(data1,data2)//数据1 数据2
        console.timeEnd("fn1")//fn1: 2001.43896484375ms
    }
}
fn1()

这种方式效率低,以队列的形式逐个执行,耗时为n个队列耗时总和

实现同步请求方法2(回调)es5推荐
function fn2() {
    console.time("fn2")
    let data1 = null
    let data2 = null
    request1().then(d1=>{
        data1 = d1
        if (data2)
            handel()
    })
    request2().then(d2=>{
        data2 = d2
        if (data1)
            handel()
    })
    function handel() {
        console.log(data1,data2)//数据1 数据2
        console.timeEnd("fn2")// fn2: 1001.375ms
    }
}
fn2()

很明显,这种方式效率比fn1方法效率高n倍(n为执行异步方法数) 方法并列执行,在es5通常用这种方式处理异步信息 耗时为队列最长一项的耗时

实现同步请求方法3(async,await)
async function fn3() {
        console.time("fn3")
        let data1 = null
        let data2 = null
        await request1().then(data=>{
            data1 = data
        });
        await request2().then(data=>{
            data2 = data
        });
        console.log(data1,data2)//数据1 数据2
        console.timeEnd("fn3")//fn3: 2002.31689453125ms
    }
	fn3()

这种方式效率低,以队列的形式执行,与fn1雷同 调用wait函数时加上了await修饰符,导致主流程的执行必须要等待wait函数执行完才会陆续执行后续函数 相当于 await wait() => promise -> wait() -> resolve()。 但是wait函数本身又写了一个promise,整个promise会setTimeout才resolve 相当于本身wait函数 => promise -> setTimeout(resolve)。 那么整个串起来,流程有点类似下面这样子,promise的嵌套,只有等内部wait函数的promise -> resolve之后 才会将外部的promise -> resolve掉。 然后再去执行下一个wait函数。 main -> wait -> promise -> (promise -> setTimeout(resolve))(resolve) 写入微任务队列,微任务队列里再写入任务队列,都是需要时间

实现同步请求方法3(async,await)es6推荐
async function fn4() {
        console.time("fn4")
        let data1 = null
        let data2 = null
        const r1 = request1()
        const r2 = request2()
        await r1.then(data=>{
            data1 = data
        });
        await r2.then(data=>{
            data2 = data
        });
        console.log(data1,data2)//数据1 数据2
        console.timeEnd("fn4")//fn4: 1001.7919921875ms
    }
	fn4()

这种方式效率高类似fn2方法,在es6中,使用这种方式处理异步信息是不二的选择 异步请求会按顺序发起。而这个过程是不需要互相依赖等待的。 等到wait的时候,其实是比较那个异步耗时最多。就会等待最长。最长的耗时就是整体的耗时。 如果在业务中,两个异步没有依赖关系。应该是后面这种写法。

return和promise
function fn5() {
        console.time("fn5")
        let data1 = null
        let data2 = null
        request1().then((res) => {
            data1 = res
            return request2()
        }).then(res=>{
            data2=res
            console.log(data1, data2)//数据1 数据2
            console.timeEnd("fn5")//fn5: 2002.428955078125ms
        })
    }
    fn5()

与fn1 fn3雷同,不建议这样使用 Promise 实现了链式调用,也就是说每次 then 后返回的都是一个全新 Promise 如果我们在 then 中 return ,return 的结果会被 Promise.resolve() 包装 无法取消 Promise ,错误需要通过回调函数来捕获

Promise.all方法
 function fn6() {
        console.time("fn6")
        let data1 = null
        let data2 = null
        const r1 = request1()
        const r2 = request2()
        Promise.all([r1, r2]).then((res) => {
            data1 = res[0]
            data2 = res[1]
            console.log(data1, data2)//数据1 数据2
            console.timeEnd("fn6")//fn6: 1002.2900390625ms
        })
    }
fn6()
在执行多个promise的时候,强烈推荐Promise.all方法

还有更好的处理方法吗,讨论一下呗

关注
打赏
1657344724
查看更多评论
立即登录/注册

微信扫码登录

0.0400s