JS异步编程

#### JS 异步编程

#### https://www.jianshu.com/p/9bfb68c585bc

#### https://blog.csdn.net/weixin_48820137/article/details/108850610

#### https://juejin.im/post/6877438201657557005/

#### JavaScript异步编程

单线程: JS执行环境中负责执行代码的线程只有一个

优点: 更安全更简单

缺点: 耗时任务阻塞

#### 同步模式---调用栈(Call stack)排队执行

#### 异步模式

不会去等待这个任务的结束才开始下一个任务

开启过后立即往后执行下一个任务

后续逻辑一般会通过回调函数的方式定义

消息队列(Queue)和事件循环(Event loop)

运行环境提供的API是以同步或异步模式的方式工作

**EventLoop** 是一种循环机制 ,不断去轮询一些队列 ,从中找到 需要执行的任务并按顺序执行的一个执行模型。

**消息队列** 是用来存放宏任务的队列, 比如定时器时间到了, 定时间内传入的方法引用会存到该队列, ajax回调之后的执行方法也会存到该队列。

一开始整个脚本作为一个宏任务执行。执行过程中同步代码直接执行,宏任务等待时间到达或者成功后,将方法的回调放入宏任务队列中,微任务进入微任务队列。

当前主线程的宏任务执行完出队,检查并清空微任务队列。接着执行浏览器 UI 线程的渲染工作,检查web worker 任务,有则执行。

然后再取出一个宏任务执行。以此循环...

**宏任务**可以理解为每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。

浏览器为了让 JS 内部宏任务 与 DOM 操作能够有序的执行,会在一个宏任务执行结束后,在下一个宏任务执行开始前,对页面进行重新渲染。

  宏任务包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、MessageChannel 等

**微任务**可以理解是在当前任务执行结束后需要立即执行的任务。也就是说,在当前任务后,在渲染之前,执行清空微任务。

所以它的响应速度相比宏任务会更快,因为无需等待 UI 渲染。

微任务包含:Promise.then、MutaionObserver、process.nextTick(Node.js 环境)等

#### Promise

三个状态 Pending Fulfilled-onFulfilled Rejected-onRejected

状态更改之后不可修改

#### promise 基本用法

const promise = new Promise(function(resolve, reject){

    // foo()

    // throw new Errow('error')

    resolve(100)

    // reject(new Error("promise rejected"))

})

// promise.then(function(value){

//    console.log('resolved', value)

// }, function(error){

//    console.log('rejected', error)

// })

// console.log('end')

#### Promise 常见误区---回调嵌套

#### Promise 链式调用

then方法会返回一个全新的Promise对象

后面的then方法就是在为上一个then返回的Promise注册回调

前面then方法中的回调函数的返回值会作为后面then方法回调的参数

如果回调中返回的是Promise, 那么后面then方法的回调会等待它的结束

let promise2 = promise.then(function(value){

    console.log('resolved', value)

}, function(error){

    console.log('rejected', error)

}) .then(function(value){

    console.log('resolved', value)

}, function(error){

    console.log('rejected', error)

}) .then(function(value){

    console.log('resolved', value)

}, function(error){

    console.log('rejected', error)

})

console.log(promise2 === promise)

promise.then(function(value){

    console.log('resolved', value)

}).catch(error => {

    console.log("error", error)

})

#### Promise 异常处理

Promise实例的catch方法 then方法中的失败回调

区别: (1)then注册失败回调只能捕获到前一个promise的异常

(2)catch是给整个Promise链条注册的失败回调

#### Promise 静态方法

resolve() reject()

Promise 静态方法 Promise.resolve() Promise.reject()

三种是等价的  有thenable接口的函数

Promise.resolve('f00').then( value => {

    console.log('resolve', value)

})

Promise.resolve({

    then: (onFulfilled, onRejected) => {

        onFulfilled('f00')

    }

}).then(value => {

    console.log(value)

})

new Promise((resolve, reject) => {

    resolve('f00')

}).then(value => {

    console.log('new', value)

})

Promise.reject(new Error('rejected')).catch(error => {

    console.log('error', error)

})

#### Promise 并行执行

all()方法 race()方法

#### Promise 执行时序 / 宏任务 微任务

微任务: 提高整体的响应能力

Promise 执行时序 / 宏任务 微任务

console.log('global start')

setTimeout(()=>{

    console.log('setTimeout1')

}, 1000)

setTimeout(()=>{

    console.log('setTimeout')

}, 100)

Promise.resolve().then(()=>{

    console.log('promise')

}).then(()=>{

    console.log('promise1')

})

console.log('global end')

#### Generator异步方案

//Generator异步方案

function *foo(){

    console.log("start")

    try{

        const res = yield 'foo'

        console.log(res, 'res')

    }catch(e){

        console.log(e, 'e')

    }


}

const generator = foo()

const result = generator.next()

console.log(result, 'result')

generator.next('bar')

generator.throw(new Error('Generator Error'))

//管理异步流程 体验Generator 函数异步方案

function *main(){

    try{

        const users = yield promise

        console.log('users', users)


        const posts = yield Promise.resolve(200)

        console.log(posts, 'posts')

    }catch(e){

        console.log(e)

    }


}

const g = main()

const result = g.next()

result.value.then(data => {

    const result2 = g.next(data)

    if(result2.done) return

    result2.value.then(data => {

        g.next(data)

    })

})

//递归执行Generator函数

const g = main()

function handleResult (result){

    if(result.done) return

    result.value.then(data => {

        handleResult(g.next(data))

    }, error => {

        g.throw(error)

    })

}

handleResult(g.next())

function co(generator){

    const g = generator()

    function handleResult (result){

        if(result.done) return

        result.value.then(data => {

            handleResult(g.next(data))

        }, error => {

            g.throw(error)

        })

    }

    handleResult(g.next())

}

co(main)

#### Async/ Await 语法糖 语言层面的异步编程标准

async function mainSync(){

    try{

        const users = await promise

        console.log('users', users)


        const posts = await Promise.resolve(200)

        console.log(posts, 'posts')

    }catch(e){

        console.log(e)

    }

}

const mains = mainSync()

mains.then(()=>{

    console.log('all completed')

})

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。