// promise
// 关于回调地狱
/**
* 回调函数带来的问题:
* 1. 代码可读性差
* 2. 回调比较多时,错误捕捉难处理
* 3. 控制反转带来的信任问题 -- 在进行异步请求时,用到第三方工具库,回调函数交由第三方库执行,
* 由第三方库决定何时执行回调函数,执行回调函数次数,第三方工具库是否百分之百可靠,带来的信任问题
*/
// try {
setTimeout(()=>{
console.log(1)
setTimeout(()=>{
try {
console.log(2)
throw new Error("error")
} catch (error) {
console.log(error)
console.log("continue……")
}
setTimeout(()=>{
console.log(3)
setTimeout(()=>{
console.log(4)
},1000)
},1000)
},3000)
},1000)
// } catch (error) {
// console.log(error)
// console.log("continue……")
// }
/**
* 回调地狱的错误捕获,只能在每个settimeout中进行try catch ,不能在整体外面使用try catch ,整体外面使用try catch ,try catch在主线程中进行,settimeout中抛出的任务在宏任务队列中,因此,整体外面添加try catch 不能捕获到settimeout中的错误
*/
// Promise
/**
* Promise 解决了回调地狱的问题
* Promise 三种状态 pending resolved rejected ,状态可以从pending转变为resolved或者rejected ,状态一旦改变后就不会再改变,通过then方法来实现链式调用
* 缺点: 创建之后,立即执行,不能中途取消
*/
/**
* 1. Promise then为promise状态改变的回调函数 通过then方法来实现链式调用
*/
new Promise((resolve)=>{
setTimeout(()=>{
console.log(1)
resolve()
},1000)
}).then(()=>{
return new Promise((resolve)=>{
setTimeout(()=>{
console.log(2)
resolve()
},1000)
})
}).then(()=>{
return new Promise((resolve)=>{
setTimeout(()=>{
console.log(3)
resolve()
},1000)
})
})
// 1 2 3
/**
* 2. Promise中的错误捕获: Promise抛出的错误不会被外面的try catch捕获,会被catch捕获
*/
try {
new Promise((resolve)=>{
throw new Error("error")
resolve()
})
.catch((reason)=>{
console.log("catch error", reason) // 捕获
})
} catch (error) {
console.log("e", error) // 无法捕获
}
/**
* Promise中的then中抛出的错误,也是不会被外部的try catch捕获,被.catch捕获,.catch相当于then的rejected状态回调函数的另一种写法
* 捕获错误最好使用catch
* catch也会返回一个新的promise,后面还可以支持继续进行链式调用
*/
try {
Promise.resolve().then(()=>{
throw new Error("error")
})
} catch (error) {
console.log("e", error) // 捕获捕获
}
Promise.resolve(1)
.then(()=>{
throw new Error("error")
})
.then(null, (reason)=>{
console.log("reason", reason) // 捕获
})
.then(()=>{
return new Promise((resolve)=>{
setTimeout(()=>{
console.log("settimeout") // 执行
resolve()
})
})
})
.catch((error)=>{
console.log("catch", error) // 未捕获到错误
}).then(()=>{
console.log("continue...") // 执行
})
/**
* 3. promise解决回调地狱的控制反转的问题:
* Promise 状态一旦改变之后不能再改变 -- 只能执行一次
* Promise 状态一旦改变立即执行回调函数 -- 控制回调函数执行的时间
*/
// generator
/**
* generator:
* 状态机,函数分段执行
* function 和 函数名之间 * ; yield执行停止的标志,next开始执行的命令
* 根据next返回结果 可以查看函数是否执行完
*/
function * gene(){
console.log(1)
yield
console.log(2)
yield
console.log(3)
yield
}
var g = gene()
console.log(g.next()) // value: undefined done: false
console.log(g.next())
console.log(g.next())
console.log(g.next()) // done: true
console.log(g.next()) // done: true
function timer(time){
return new Promise((resolve)=>{
setTimeout(()=>{
console.log(time)
resolve()
run.next()
}, time)
})
}
// 异步
function *runner(){
let p1 = yield timer(100)
let p2 = yield timer(2000)
let p3 = yield timer(300)
}
var run = runner()
run.next()
// 100 2000 300
// async/await
/**
* async/await (generator语法糖)
* async关键字放在函数function 之前, 声明函数为异步函数 ,函数返回Promise
* await 只在异步函数中起作用,放在基于promise的函数之前,代码停在该处,直到promise执行完成状态改变才执行后面的函数
* await 后面除了跟promise 还可以跟其他的任意表达式
*/
async function func(){
await new Promise((resolve)=>{
setTimeout(()=>{
console.log(1)
resolve()
}, 100)
})
await new Promise((resolve)=>{
setTimeout(()=>{
console.log(2)
resolve()
}, 500)
})
await new Promise((resolve)=>{
setTimeout(()=>{
console.log(3)
resolve()
}, 300)
})
}
func().then(()=>{
console.log("continue...")
})
// 1 2 3 continue...
/**
* 判断执行顺序:
* async函数中await之前的语句是同步执行的
* await 后面的语句属于微任务队列
*/
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 输出: script start => async1 start => async2 => script end => async1 end
async function func5(){
console.log(1)
await Promise.resolve(2)
console.log(3)
}
func5()
console.log(4)
// 1 4 3
async function func4(){
console.log(1)
await setTimeout(()=>{
console.log(2)
},300)
console.log(3)
}
func4()
setTimeout(()=>{
console.log(5)
},500)
// 1 3 2 5
/**
* ⚠️ await 后面的promise返回可能是reject 用try catch来捕获
*/
async function func2(){
try {
await Promise.reject(1)
} catch (error) {
return error
}
}
func2()
promise & generator & async/await
最新推荐文章于 2025-02-18 19:43:47 发布