01-Promise语法

1.1-Promise介绍

  • ES6教程传送门:http://es6.ruanyifeng.com/#docs/promise
  • 1.Promise是什么?
    • Promise 一个 构造函数, 用于创建Promise对象

      • Promise对象:可以理解为一个处理异步操作的容器
  • 2.Promise作用:解决回调地狱
    • 回调地狱:异步回调 层层嵌套
/*
为什么要学习Promise?1.Promise作用 : 解决回调地狱问题回调地狱 : 异步回调 层层嵌套
*///需求: 依次读取 文件  a.txt , b.txt , c.txt 这三个文件内容
const fs = require('fs');//(1)能直接按照顺序写吗?  : 不能,因为异步操作 是无序的
fs.readFile("./data/a.txt", 'utf-8', (err, data) => {if(err){console.log(err);}else{console.log(data);};
});fs.readFile("./data/b.txt", 'utf-8', (err, data) => {if(err){console.log(err);}else{console.log(data);};
});fs.readFile("./data/c.txt", 'utf-8', (err, data) => {if(err){console.log(err);}else{console.log(data);};
});//(2)解决方案 : 在回调函数中嵌套执行
//弊端 : 形成回调地狱(异步回调 层层嵌套,非常麻烦且不便于维护)
//读取文件A
fs.readFile("./data/a.txt", 'utf-8', (err, data) => {if(err){console.log(err);}else{console.log(data);//A读取成功之后开始读取Bfs.readFile("./data/b.txt", 'utf-8', (err, data) => {if(err){console.log(err);}else{console.log(data);//B读取成功之后开始读取Cfs.readFile("./data/c.txt", 'utf-8', (err, data) => {if(err){console.log(err);}else{console.log(data);}});}});}
});

1.2-Promise基本使用

  • 1.实例化Promise对象

    • 作用: 将异步操作代码 放入 Promise中

      • resolve:异步操作 成功状态
      • reject : 异步操作 失败状态
    • new Promise((resolve,reject)=>{ 你的异步操作 })
  • 2.调用then()方法处理异步操作结果
    • promise对象.then((data)=>{ 处理成功数据 },(err)=>{ 处理失败信息 });
/*
1.Promise是一个构造函数 , 返回一个Promise对象
2.使用流程(1)实例化Promise对象 : 将异步操作放入Promise中(2)调用then() 方法: 处理异步操作结果
*/const fs = require('fs');
/** 1. 实例化Promise
* @description:实例化Promise
* @param {Function}  (resolve:成功处理函数,reject:失败处理函数)=>{ 异步操作代码 }
* @return: Promise对象
*/const p1 = new Promise((resolve,reject)=>{//读文件fs.readFile('./data/a.txt','utf8',(err,data)=>{if(err == null){ /* (1)异步操作成功,则执行 resolvce()(2)resolve会把把promise对象的状态从 pending进行中 改为 fulfilled成功(3)该方法本质是调用 then() 中的第一个方法*/resolve(data);}else {/* (1)异步操作失败,则执行 reject()(2)reject会把把promise对象的状态从 pending进行中 改为 rejected失败(3)该方法本质是调用 then() 中的第二个方法*/reject(err); }});});/* 2. p1.then() : 处理异步操作结果 */p1.then((data)=>{//成功了,打印文件数据console.log(data);},(err)=>{//失败了,打印错误信息console.log(err);});

1.3-Promise特点介绍(原理篇)

promise本身并没有改变异步的顺序,而是通过操作异步结果的顺序从而'间接'控制异步的顺序

promise本质 不是控制 异步代码的执行顺序(无法控制) , 而是控制异步代码结果处理的顺序

**promise本身只是一个容器,真正异步的是它的两个回调resolve()和reject() **

/*** 1.promise对象有三个状态.a. pending(进行中)b. fulfilled(已成功)c. rejected(已失败)* 2.Promise对象的状态改变, 只有两种可能:a. 从pending变为fulfilled* 此时应该执行 resolve();b. 从pending变为rejected。* 此时应该执行 reject();* 3.promise在创建对象的时候,里面的代码会立即执行.a. promise创建时,里面的代码还是异步无序操作b. promise的原理是,利用then方法将异步操作的结果 按照顺序执行*** 总结: 不要在创建promise的时候去处理异步操作结果,而应该通过 then() 方法来处理 **** 4.promise解决回调地狱原理 : 在then方法中返回一个promise对象*** 在上一个promise的then方法中,返回下一个promise **** 5.坤哥结语 : promise本质 不是控制异步代码的执行顺序(无法控制) , 而是控制异步代码结果处理的顺序
*/const fs = require('fs');//(1) 创建三个异步操作  promise//读取文件A
const p1 = new Promise((resolve,reject)=>{//读文件fs.readFile('./data/a.txt','utf8',(err,data)=>{if(err == null){ //成功resolve(data);}else {//失败reject(err); }});
});//读取文件B
const p2 = new Promise((resolve,reject)=>{//读文件fs.readFile('./data/b.txt','utf8',(err,data)=>{if(err == null){ //成功resolve(data);}else {//失败reject(err); }});
});//读取文件C
const p3 = new Promise((resolve,reject)=>{//读文件fs.readFile('./data/c.txt','utf8',(err,data)=>{if(err == null){ //成功resolve(data);}else {//失败reject(err); }});
});// (2)按照顺序处理异步操作结果
p1.then((data)=>{//第一个异步结果console.log(data);return p2;//返回下一个promise
}).then((data)=>{ // 第二个异步结果  (由于p1.then方法返回的是p2,而p2也有自己的then,所以可以继续调用p2的then方法)console.log(data);return p3;//返回下一个promise
}).then((data)=>{ // 第三个异步结果  console.log(data);
});

1.4-Promise解决回调地狱封装

const fs = require('fs');//1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {let p = new Promise((resolve, reject) => {//读文件fs.readFile(`./data/${fileName}.txt`,'utf-8', (err, data) => {if (err == null) {//成功resolve(data);} else {//失败reject(err);}});});return p;
};//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.//开始读取a
getPromise('a').then((data)=>{console.log(data);//继续读取breturn getPromise('b');
}).then((data)=>{console.log(data);//继续读取creturn getPromise('c');
}).then((data)=>{console.log(data);
});//异步回调队列结束

1.5-Promise对象的catch方法

  • catch:用于捕获异步操作的错误信息
const fs = require("fs");/*
promise实例对象的catch方法 : 用于捕获异步操作的错误信息
*///1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {let p = new Promise((resolve, reject) => {//读文件fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {if (err == null) {//成功resolve(data);} else {//失败reject(err);}});});return p;
};//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.//开始读取a
getPromise('a').then((data)=>{console.log(data);//继续读取breturn getPromise('b');
}).then((data)=>{console.log(data);//继续读取creturn getPromise('c');
}).then((data)=>{console.log(data);
}).catch((err)=>{//以上三个异步操作,只要有任何一个出错,都会执行errconsole.log(err);
});

1.6-Promise对象的all方法

  • all

    • 将多个Promise合并成一个Promise
    • 所有异步全部执行完毕才会执行then方法
const fs = require("fs");/*
1. promise实例对象的all方法 : 将多个Promise合并成一个Promise* 所有异步全部执行完毕才会执行then方法2. 解决需求: a , b , c 同时执行完毕
*///1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {let p = new Promise((resolve, reject) => {//读文件fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {if (err == null) {//成功resolve(data);} else {//失败reject(err);}});});return p;
};//2.解决需求: a , b , c 同时执行完毕
let pa = getPromise('a');
let pb = getPromise('b');
let pc = getPromise('c');
//将三个异步操作合并成一个Promise
let pAll = Promise.all([pa,pb,pc]);//开始读取a
// 三个promise都成功后,才去执行pAll.then的第一个方法.
// 只要有一个失败了,就去执行catch里面的函数.
pAll.then((data)=>{console.log(data);//data是一个数组,存储每一个promise的成功结果
}).catch((err)=>{console.log(err);
});

1.7-Promise对象的race方法

  • race

    • 将多个Promise合并成一个Promise
    • 任何一个异步 执行完毕就会执行then方法
const fs = require("fs");/*
1. promise实例对象的race方法 : 将多个Promise合并成一个Promise* 任何一个异步  执行完毕就会执行then方法2. 解决需求: a , b , c 任意一个成功
*///1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {let p = new Promise((resolve, reject) => {//读文件fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {if (err == null) {//成功resolve(data);} else {//失败reject(err);}});});return p;
};//2.解决需求: a , b , c 同时执行完毕
let pa = getPromise('a');
let pb = getPromise('b');
let pc = getPromise('c');
//将三个异步操作合并成一个Promise
let pAll = Promise.race([pa,pb,pc]);//开始读取a
// 三个promise任何一个成功,就去执行pAll.then的第一个方法.  (一旦成功一个,其他不再执行)
pAll.then((data)=>{console.log(data);//data是第一个执行成功的primise异步结果
}).catch((err)=>{console.log(err);
});

1.8-[拓展了解]axios底层基于promise

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><script>/* 1.axios() : 返回值是promise实例对象2.axios() : 底层是基于promise技术封装xhr*///手写axios底层原理function axios(obj){return new Promise((resolve,reject)=>{//(1).实例化ajax对象let xhr = new XMLHttpRequest()//(2).设置请求方法和地址ii//get请求的数据直接添加在url的后面 格式是 url?key=valuexhr.open('get', obj.url )//(3).发送请求xhr.send()//(4).注册回调函数xhr.onload = function() {resolve( JSON.parse(xhr.responseText) )}})}// const p1 = axios()// axios()方法本质是创建promise对象并返回// console.log( p1 )//promise实例对象Promise.all( [axios({url:'https://autumnfish.cn/api/joke/list?num=10'}) , axios({url:'https://autumnfish.cn/fruitApi/fruits'})] ).then(res=>{console.log(res)})</script>
</body>
</html>

02-ES6异步函数async与await

​ 异步函数async相当于是promise语法的 “高级写法”

​ ES2017中引入的更为高级的异步处理机制,async函数,可以让异步的处理变的更加便捷

传送门:阮一峰-async函数

  • 一句话概括: async函数相当于是promise异步函数的另一种高级写法

    • promise虽然解决了异步回调地狱(回调函数层次嵌套)的问题,但是写起来的时候仍然需要嵌套(链式语法嵌套,需要在上一个promise对象的then方法中返回下一个promise)
  • 1.传统的promise异步函数(模拟依次异步读取文件a,b,c)

const fs = require("fs");/*
promise实例对象的catch方法 : 用于捕获异步操作的错误信息
*///1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {let p = new Promise((resolve, reject) => {//读文件fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {if (err == null) {//成功resolve(data);} else {//失败reject(err);}});});return p;
};//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.//开始读取a
getPromise('a').then((data)=>{console.log(data);//继续读取breturn getPromise('b');
}).then((data)=>{console.log(data);//继续读取creturn getPromise('c');
}).then((data)=>{console.log(data);
}).catch((err)=>{//以上三个异步操作,只要有任何一个出错,都会执行errconsole.log(err);
});
  • 2.使用async异步函数

  • async语法如下

    • (1)函数前面使用async修饰
    • (2) 函数内部,promise操作使用await修饰
      • await 后面是promise对象, 左侧的返回值就是这个promise对象的then方法中的结果
      • await必须要写在async修饰的函数中,不能单独使用,否则程序会报错
    • (3)async函数内部的异常需要通过try,catch来捕获
const fs = require("fs");/*
promise实例对象的catch方法 : 用于捕获异步操作的错误信息
*///1.封装一个函数 :  根据文件名生成  文件读取的promise
function getPromise(fileName) {let p = new Promise((resolve, reject) => {//读文件fs.readFile(`./data/${fileName}.txt`, 'utf-8', (err, data) => {if (err == null) {//成功resolve(data);} else {//失败reject(err);}});});return p;
};//2.解决需求: 要先读a, 读完a后读b, 读完b后读c.// async和await异步函数 :  这两个关键字只能用于函数, 所以用的时候一定要放在函数里面用/*
async关键字:  修饰函数。  表示这个函数内部有异步操作。
await关键字:  等待异步执行完毕。(1)await只能用于被async修饰的函数中。  只有当await后面的异步操作执行完毕后,才会继续执行后面代码(2)await 后面 只能是promise对象
*/const readFile = async () => {let data1 = await getPromise('a')console.log(data1)let data2 = await getPromise('b')console.log(data2)//async异步函数的错误信息要用try-catch来捕捉try {let data3 = await getPromise('c')console.log(data3)} catch (err) {console.log(err)}
}readFile()

03-异步函数实际应用场景

1.水果列表

  • 请求地址:https://autumnfish.cn/fruitApi/fruits
  • 请求方法:get
  • 请求参数:
  • 响应内容:json数据

2.水果详情

  • 请求地址: https://autumnfish.cn/fruitApi/fruit/:id
  • 请求方法: get
  • 请求参数:id,在 url 中直接传递
  • 响应内容:json
    • icon:base64 的图片,直接设置给src即可使用

​ 需求: (1)先请求水果列表 (2)默认请求第一个水果详细信息

思考: 这两个ajax有没有顺序要求?

是不是一定要先发送第一个ajax,只有第一个ajax响应了。才可以拿到水果的id来发第二个ajax?

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><button class="btn1">按钮1:点我发送ajax</button><br><button class="btn2">按钮2:点我发送ajax</button><!-- 导入axios --><script src="./axios.js"></script><script>/* 需求:(1)先请求水果列表 (2)然后默认请求第一个水果详情  *///没有使用异步函数document.querySelector('.btn1').addEventListener('click',function(){//(1)请求水果列表axios({url:'https://autumnfish.cn/fruitApi/fruits',method:'get',}).then(res=>{//成功回调console.log(res)//(2)请求水果详情axios({url:`https://autumnfish.cn/fruitApi/fruit/${res.data.data[0].id}`,method:'get',}).then(res=>{//成功回调console.log(res)})})})//使用异步函数document.querySelector('.btn2').addEventListener('click',async function(){//(1)请求水果列表let res1 = await axios({url:'https://autumnfish.cn/fruitApi/fruits',method:'get'})console.log(res1)//(2)请求水果详情let res2 = await axios({url:`https://autumnfish.cn/fruitApi/fruit/${res1.data.data[0].id}`,method:'get'})console.log(res2)})</script>
</body>
</html>

04-JS执行原理(Event Loop事件循环、微任务、宏任务)

1.1-事件循环Event Loop概念介绍

​ 事件循环Event Loop又叫事件队列,两者是一个概念

  • 1.什么是事件循环 : 浏览器解析执行js代码的一种运行机制(执行规则)

    • 事件循环指的是js代码所在运行环境(浏览器、nodejs)编译器的一种解析执行规则。

      • 在js中讨论事件循环是没有意义的, : 事件循环不属于js代码本身的范畴,而是属于js编译器的范畴

        • 说人话: js代码可以理解为是一个人在公司中具体做的事情, 而 事件循环 相当于是公司的一种规章制度。 两者不是一个层面的概念。

1.2-微任务、宏任务概念介绍

  • 1.微任务与宏任务就属于js代码的范畴

  • 2.js代码主要分为两大类: 同步代码、异步代码

  • 3.异步代码又分为:微任务与宏任务

  • 同步任务:同步任务不需要进行等待,必须立即看到执行结果,比如console

  • 异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求

  • 异步任务,又可以细分为宏任务和微任务。下面列举目前学过的宏任务和微任务。

任务(代码) 宏/微 任务 环境

1.3-事件循环Event Loop执行机制

  • 1.进入到script标签,就进入到了第一次事件循环.
  • 2.遇到同步代码,立即执行
  • 3.遇到宏任务,放入到宏任务队列里.
  • 4.遇到微任务,放入到微任务队列里.
  • 5.执行完所有同步代码
  • 6.执行微任务代码
  • 7.微任务代码执行完毕,本次队列清空
  • 寻找下一个宏任务,重复步骤1
    • 以此反复直到清空所以宏任务,这种不断重复的执行机制,就叫做事件循环

05-事件循环Event Loop面试题大礼包

  • (1)promise嵌套promise : 先走嵌套的then,后走外层then

    • 原理: promise本身是一个同步的代码(只是容器),只有容器等同步走完了,才会走微任务then()
  • (2)await : 下面的才是微任务, 右边的代码还是立即执行

    • await微任务可以转换成等价的promise微任务分析

      • await 函数名()
        代码块
        //等价于下面代码
        函数名().then(()=>{ 代码块 })
        
      • await fn()
        console.log(1111)
        //等价于
        fn().then(()=>{console.log(1111)
        })
        
  • (3)script标签本身是一个宏任务

    • 当页面出现多个script标签的时候,浏览器会把script标签作为宏任务来解析

      • 圈重点 : 解析不代表执行

1.1-第一题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>console.log(1)setTimeout(function () {console.log(2)}, 0)const p = new Promise((resolve, reject) => {resolve(1000)})p.then(data => {console.log(data)})console.log(3)</script>
</body></html>

1.2-第二题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>console.log(1)setTimeout(function () {console.log(2)new Promise(function (resolve) {console.log(3)resolve()}).then(function () {console.log(4)})})new Promise(function (resolve) {console.log(5)resolve()}).then(function () {console.log(6)})setTimeout(function () {console.log(7)new Promise(function (resolve) {console.log(8)resolve()}).then(function () {console.log(9)})})console.log(10)</script>
</body></html>

1.3-第三题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>console.log(1)setTimeout(function () {console.log(2)}, 0)const p = new Promise((resolve, reject) => {console.log(3)resolve(1000) // 标记为成功console.log(4)})p.then(data => {console.log(data)})console.log(5)</script>
</body></html>

1.4-第四题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>new Promise((resolve, reject) => {resolve(1)new Promise((resolve, reject) => {resolve(2)}).then(data => {console.log(data)})}).then(data => {console.log(data)})console.log(3)</script>
</body></html>

1.5-第五题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>setTimeout(() => {console.log(1)}, 0)new Promise((resolve, reject) => {console.log(2)resolve('p1')new Promise((resolve, reject) => {console.log(3)setTimeout(() => {resolve('setTimeout2'); //'混淆你的'console.log(4)}, 0)resolve('p2')}).then(data => {console.log(data); //'p2'})setTimeout(() => {resolve('setTimeout1'); //'混淆你的'console.log(5)}, 0)}).then(data => {console.log(data); //'p1'})console.log(6)</script>
</body></html>

1.6-第六题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>console.log(1);async function fnOne() {console.log(2);await fnTwo(); // 右结合先执行右侧的代码, 然后等待console.log(3);}async function fnTwo() {console.log(4);}fnOne();setTimeout(() => {console.log(5);}, 2000);let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码console.log(6);resolve();console.log(7);})setTimeout(() => {console.log(8)}, 0)p.then(() => {console.log(9);})console.log(10);</script><script>console.log(11);setTimeout(() => {console.log(12);let p = new Promise((resolve) => {resolve(13);})p.then(res => {console.log(res);})console.log(15);}, 0)console.log(14);</script>
</body></html>

1.7-第七题

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><script>console.log(1)new Promise((resolve, reject) => {resolve(2)}).then(res => {console.log(res)})setTimeout(() => {console.log(3)})console.log(4)</script><script>console.log(5)</script><script>new Promise((resolve,reject)=>{resolve(6)}).then(res=>{console.log(res)})setTimeout(()=>{console.log(7)})console.log(8)</script><script>console.log(9)setTimeout(()=>{console.log(10)})</script>
</body></html>

Promise和事件循环相关推荐

  1. jsp循环输出表格_「翻译」JS可视化学习之七:Promise、事件循环和异步2

    喜欢排队吧,它能保护你的时间和精力 - 排队纪律维护员Event Loop Promise和事件循环概览图 请注意上面这张图,Promise和事件循环的那些事,将在这个图上缓缓展开. 微任务和(宏)任 ...

  2. es5如何实现promise_ES5实现Promise(1) - 事件循环机制

    因为公司业务面向国企以及传统企业,所以代码需要能够在ie9以上运行,所以在项目中无法用一些新技术.比如ES6的Promise,这个Promise真的是太好使了,就跟便秘时使了开塞露一般.由于Promi ...

  3. 原生js循环展示dom_【前端面试】用一道题讲 js 的事件循环队列

    昨天去面了滴滴,一口气面了三面,考了 promise 和事件循环.之前的猿辅导也考察了这些,几乎所有的大厂中厂都一定会考原生 js 的事件循环队列. 今天,我把昨天考察的原题拿出来分析一下. setT ...

  4. 5调用外部浏览器打开代码_浏览器事件循环

    浏览器运行过程中会同时面对多种任务,用户交互事件(鼠标.键盘).网络请求.页面渲染等.而这些任务不能是无序的,必须有个先来后到,浏览器内部需要一套预定的逻辑来有序处理这些任务,因此浏览器事件循环诞生了 ...

  5. 事件循环中的宏任务和微任务执行顺序

    事件循环中的宏任务和微任务执行顺序 先来了解一下事件循环.宏任务.微任务和Promise 1.事件循环(Event Loop)运行机制 执行一个宏任务(栈中没有就从事件队列中获取) 执行过程中如果遇到 ...

  6. php循环套循环_PHP中的事件循环简介

    php循环套循环 PHP developers are always waiting for something. Sometimes we're waiting for requests to re ...

  7. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)...

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

  8. html5 promise,从HTML5与PromiseA+规范来看事件循环

    写在最前 本次分享一下从HTML5与PromiseA+规范来迅速理解一波事件循环中的microtask 与macrotask. 欢迎关注我的博客,不定期更新中-- JavaScript小众系列开始更新 ...

  9. 【转载】浏览器事件循环机制(event loop)

    首先,本文转自https://juejin.im/post/5afbc62151882542af04112d 当我看完菲利普·罗伯茨的 javascript event loop的演讲的时候,就对于事 ...

最新文章

  1. 奔跑吧2015,个推一月活动走起
  2. torch转onnx错误 exit code -1073741819
  3. awk -f 分隔符 命令_详解!!!awk参见使用命令
  4. zhlan--Python中常见的几种格式化输出
  5. psutil python库
  6. UE4删除C++Classes下的类
  7. 十分钟完成的操作系统编写 你信吗?
  8. adb服务无法开启问题解决方法
  9. unix域套接字UDP网络编程
  10. windows 安装 dnw、fastboot 驱动的时候遇到问题(数字签名)
  11. python编程求导数_SciPy函数求导数
  12. 【Python】pyqt5-----QLabel
  13. 软件架构师的培养与认证
  14. redis设计与实现-数据库篇
  15. 计算:[(1*2*4+2*4*8+...+n*2n*4n)/(1*3*9+2*6*18+...+n*3n*9n)]^2的值
  16. IP协议详解(ip头部,ip分片,ip路由选择)
  17. 程序员练级攻略(2018) --左耳朵耗子
  18. 二阶非齐次微分方程竖式解法(基本型)求解器(不支持复数运算)
  19. uniapp个人体会
  20. Android手写优化

热门文章

  1. 荣耀手机装联通卡显示无服务器,荣耀X10用不了物联网卡(联通物联卡3g却不能上网)...
  2. 三行九个点,用4条线段连接(扩展,用3条,用1条)
  3. Cubby提供Dropbox 2倍推荐存储空间 各大云储存容量与价格PK
  4. PCIe学习笔记之pcie初始化枚举和资源分配流程代码分析
  5. 什么是透视变形的opencv和python
  6. 如何使用Python打开一个TXT文件
  7. 基于动态手势识别的酷狗音乐播放器控制
  8. WIN7笔记本 用户账户登录密码忘记/错误解决方法
  9. Set Similarity
  10. 使用Excel对国外B2B电商平台进行描述性数据分析