JavaScript异步编程

JS异步编程的介绍

首先说说为什么会有JS异步编程
众所周知,JS是单线程模式工作的,因为JS是运行在浏览器端的脚本语言,目的是为了实现页面的交互,那么因为页面交互主要是DOM操作,从而决定了它必须使用单线程模式工作,否则就会出现特别复杂的线程同步问题。
这种模式优点是更安全、更简单,缺点就是如果在代码执行中遇到一个特别耗时的操作,那么后面的代码就必须等待这个操作结束以后才可以执行。
所以,为了解决像这样的情况,JS将任务的执行模式分成了两种,分别是同步模式(Synchronous)异步模式(Asynchronous)

同步模式和异步模式

  • 同步模式
    至上而下依次执行,代码可读性高
console.log('global begin')
function bar () {
    console.log('bar')
}
function foo() {
    console.log('foo')
    bar()
}
foo()
console.log('global end')

// global begin
// foo
// bar
// global end
  • 异步模式
    通过事件循环和消息队列实现的
console.log('g1 begin')
setTimeout(function timer1() {
    console.log('timer1')
}, 1800) // 这里如果把时间改为 >= 2000 则结果 timer1 会在 timer3 之后打印

setTimeout(function timer2() {
    console.log('timer2')
    setTimeout(function timer3() {
        console.log('timer3')
    }, 1000)
}, 1000)
console.log('g1 end')

// g1 begin
// g1 end
// timer2
// timer1
// timer3

Promise

状态只有三种 PENDING FULFILLED REJECTED
单向转换,且状态不可再更改
pending —> fulfilled
pending —> rejected

new Promise((resolve, reject) => {
    resolve('success')
    // reject('error')
})
  • 链式调用
let promise = new Promise((resolve, reject) => {
    resolve('success')
})
promise
    .then(v => {
        console.log(v) // success
        return '2'
    })
    .then(v => console.log(v)) // 2
    .then()
    .then()
  • 静态方法
// 直接成功
Promise.resolve()
// 直接失败
Promise.reject()
  • Promise 并行
// all() 和 race() 的区别
Promise.all() // 是等待所有的异步任务都执行结束以后才会结束
Promise.race() // 当有一个任务结束的时候就结束

宏任务、微任务

目前大部分异步调用都是作为宏任务执行的, 如:setTimeout…

作为微任务处理的有:

Promise 和 MutationObserver 和 nodeJs中的 process.nextTick

Generator 生成器函数

// 带有 * 的函数为生成器函数
function * foo() {
    console.log('start')
    // yield 会暂停执行,但不会结束,当下次再调用 next() 的时候会继续往下执行
    try {
        let res = yield 'foo' 
        console.log(res)
    } catch (e) {
        console.log(e)
    }
}
// 生成器函数调用不会立即执行
const generator = foo()
// 当手动调用 next() 方法时才会执行
// 如果在next()中传入参数,则会作为 yield 语句的返回值
let result = generator.next('bar')
// result返回值 为一个对象,存在两个参数: value 和 done
// value 为 生成器函数 yield 的返回值
// done 为判断当前生成器是否全部执行完成 值为: true or false
// 当调用 throw 方法抛出异常时,可以在函数中通过 try catch 接收
generator.throw(new Error('Generator Error'))

Async / Await 语法糖

语言层面的异步编程标准
Generator功能一样,只是把 * 换成 async, yield换成await

async function () {
    let res = await xxx
    console.log(res)
}
全局捕获异常*
  • unhandledrejection
// 在浏览器上
window.addEventListener('unhandledrejection', event => {
    const { reason, promise } = event
    console.log(reason, promise)
    // reason => Promise 失败原因,一般是一个错误对象
    // promise => 出现异常的 Promise 对象
    event.preventDefault()
}, false)
// 在 node 上
process.on('unhandledRejection', (reason, promise) => {
    console.log(reason, promise)
    // reason => Promise 失败原因,一般是一个错误对象
    // promise => 出现异常的 Promise 对象
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hh_self

您的鼓励将是我原创最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值