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和promisefunction 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方法
还有更好的处理方法吗,讨论一下呗