美文网首页
js同步异步编程(2)

js同步异步编程(2)

作者: 路上灵魂的自由者 | 来源:发表于2019-02-26 14:11 被阅读2次

js中的同步异步编程

> 浏览器是多线程的,JS是单线程的(浏览器之分配一个线程来执行JS)

> 进程大线程小: 一个进程中包含多个线程,例如在浏览器中打开一个HTML页面就占用了一个进程,加载页面的时候,浏览器分配一个西线程去计算DOM树,分配其他的线程去加载对应得资源文件...在分配一个线程去自上而下执行JS

同步编程: 在一个线程上(主栈/主任务队列),同一个时间只能做一件事情,当前事情完成才能进行下一个事情(先把一个任务进栈执行,执行完出栈,在把下一个任务进栈...)

异步编程:在主栈中执行一个任务,但是发现这个任务是一个异步得操作,我们会把它移除主栈,放到等待栈任务队列中(此时浏览器会分配其他线程监听异步任务是否到达指定的执行时间),如果主栈任务执行完成,监听者会把到达时间的异步任务重新放到主栈中执行...

异步任务:

    [宏任务]: macro task

        - 定时器

        - 事件绑定

        - ajax

        - 回调函数

        - node中fs可以进行异步得I/O操作

    [微任务]: micro task

        - Promise(async/await)

            Promise并不是完全的同步,当再Excutor中执行resolve或者reject的时候,此时的异步操作,会执行then/catch等。当主栈完成后,才会去调用resove/reject吧存放的方法执行

        - process.nextTick

    执行顺序优先级

        SYNC => MICRO(微任务) => MACRO(宏任务)

    所以JS中的异步编程仅仅是根据某些机制来管控任务的执行顺序,不存在同时执行两个任务这一说法。

定时器

setTimeout(()=>{console.log(1)},20)

setTimeout(()=>{console.log(2)},0)  //=>默认会有最小的等待时间(v8一般是5-6MS)

console.time('WHILE')

let i = 0;

while(i<=10){i++}

console.timeEnd('WHILE')

setTimeout(()=>{console.log(3)},10)

console.log(4)

// 4 2 1 3

解析:

AJAX

// => AJAX任务开始: SEND

// => AJAX任务结束: 状态为4

let xhr = new XMLHttpRequest();

xhr.open('GET','xxx.text',false);

/*放到等待去的时候,此时状态是1*/

xhr.onreadystatechange=()=>{

    console.log(xhr.readyState)  //=>4

}

xhr.send();

/* 状态为4的时候,主栈空闲 */


let xhr = new XMLHttpRequest();

xhr.open('GET','xxx.text',false);

xhr.send();

/* 状态已经为4了 */

xhr.onreadystatechange=()=>{ //状态改变才会出发,放到等待区的时候状态已经为4了,不会再改变了,所以不会再执行这个方法了(啥都不会输出)

console.log(xhr.readyState)

}


let xhr = new XMLHttpRequest();

xhr.open('GET','xxx.text');

xhr.send();   //=》异步操作,执行send后,有一个线程是去请求数据,主栈会空闲下来

/*放等待区之前状态是1*/

xhr.onreadystatechange=()=>{

console.log(xhr.readyState) //2 3 4

}

/*主栈有空闲了*/

// 状态为2,把函数执行

// 状态为3,把函数执行

// 状态为4,把函数执行

Promise

/*

console.log(1)

new Promise((resolve,reject)=>{

    // => new Promise的时候会立即吧excutor函数(也就是传递的回调函数)执行,所以Promise本身可以理解为同步的

    console.log(2);

    resolve(); //Promise内部机制,执行resolve会把之前基于then存放的方法执行

}).then(()=>{ //执行完成excutor,紧接着执行then,执行then方法,会把传递的回调函数放到指定的容器中,等待出发执行(Promise内部机制)

    console.log(3)

})

console.log(4)

*/


console.log(1)

new Promise((resolve,reject)=>{

    console.log(2);

    resolve();

}).then(()=>{

    console.log(3)

})

console.log(4)

async-await

// ES7中新增加对Promise操作的新语法,async/await(使用await必须保证当前方法是基于async修饰的)

/*

function AA(){

    return new Promise((resolve,reject)=>{

        setTimeout(()=>{

            Math.random()<0.5?reject(100):resolve(200)

        },0)

    })

}

fn()

console.log(1)

async function fn(){

console.log(2)

let res = await AA();  //先把AA执行。等待AA中的PROMISE完成(不论成功和失败),都会把最后的处理结果获取到赋值给RES,拿到后在执行后面的代码(有人说:AWAIT把是异步的操作同步化)

console.log(res)

console.log(3)

}

console.log(4)

// fn()

*/

function AA(){

    console.log(1)

    return new Promise((resolve,reject)=>{

            setTimeout(()=>{

                resolve(200)

            },0)

    })

}

async function fn(){

    console.log(2)

    let res = await AA();

    await执行的原理

    /*

       1.先把AA执行,返回一个Promise实例

       2.它会暂时跳出当前正在执行的函数(Fn),也就是await后面的代码暂时先不执行(把后面的代码从主栈中移除,放到等待区中)

       3.主栈暂时空闲

      4.当主栈中的其他任务执行完成(主栈空闲),并且AA中的PROMISE也已经计算完成最后的结果,再把之前的第二步移到等待区的内容,重新那回到主栈中执行

*/

    console.log(3)

}

fn()

console.log(4)

// while(true){

// }

// => 2 1 4 3 AWAIT并不是同步


// 面试题(涉及到宏任务与微任务

async function async1(){

    console.log('async1 start')

    await async2(); //先执行async2(),在等待

    console.log('async1 end')

}

async function async2(){

    console.log('async2')

}

console.log('script start')

setTimeout(()=>{

    console.log('setTimeout')

},0)

async1();

new Promise(function(resolve){

     console.log('promise1')

resolve();

}).then(function(){

    console.log('promise2')

})

console.log('script end')

//执行结果

// "script start"  "async1 start"  "async2"  "promise1"  "script end"  "async1 end” 或者“promise2”(根据不同的V8版本,是不一样的)  “setTimeout”

相关文章

  • js同步异步编程(2)

    js中的同步异步编程 > 浏览器是多线程的,JS是单线程的(浏览器之分配一个线程来执行JS) > 进程大线程小: ...

  • JS中的异步编程

    JS中的同步编程和异步编程 同步编程:任务是按照顺序依次处理,当前这件事没有彻底做完,下一件事是执行不了的 异步编...

  • JS中的同步异步

    目录 1. 在JS中,什么是同步异步? 2. JS中常见的异步代码 1. 在JS中,什么是同步异步? 通俗解释一下...

  • js同步编程与异步编程

    /* * JS中的同步编程和异步编程 * 同步编程: 任务是按照顺序依次处理,当前这件事没有彻底昨晚,下一件事是...

  • 异步编程的困惑

    《深入浅出 Node.js》阅读随笔 众所周知,Node.js 虽然也有部分同步编程的方式,但主要还是以后异步编程...

  • 异步和回调

    JS异步编程原型 如果能直接拿到结果就是同步如果不能直接拿到结果就是异步 异步 以AJAX为例 request.s...

  • js同步与异步编程

    JS是单线程的:js傻,做着当前的事,没完成之前,绝不会做下一件事。 JS中的两种编程思想:同步、异步。 1、同步...

  • 为什么要使用异步 PHP

    同步编程与异步编程的区别 在讨论异步 PHP 的优点之前,让我们快速回顾一下同步编程模型和异步编程模型之间的区别。...

  • 异步_ promise

    阮一峰 js的4种异步编程方法其他的一些异步编程方法 js 异步编程方法 一,回调函数 假定有两个函数f1和f2...

  • ES6学习--异步编程--Generator

    异步编程 : (异步编程的语法目的就是让异步编程更像同步编程) 回调函数利用回调函数实现异步编程本身没有问题, 问...

网友评论

      本文标题:js同步异步编程(2)

      本文链接:https://www.haomeiwen.com/subject/dveayqtx.html