重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,天天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的能够加入winter的专栏学习【原文有winter的语音】,若有侵权请联系我,邮箱:kaimo313@foxmail.com。前端
一个
JavaScript
引擎会常驻于内存中,它等待着宿主
把JavaScript
代码或者函数传递给它执行。浏览器
一、ES3
版本以及以前,JavaScript
自己尚未异步执行代码的能力,宿主环境
传递给 JavaScript
引擎,而后按顺序执行,由宿主发起任务。异步
二、ES5
以后,JavaScript
引入了 Promise
,不须要浏览器的安排,JavaScript
引擎自己也能够发起任务。async
三、采纳JSC
引擎术语,把宿主发起的任务称为宏观任务
,把JavaScript
引擎发起的任务称为微观任务
。函数
JavaScript
引擎等待宿主环境分配宏观任务,在 Node 术语中,把这个部分称为事件循环
。学习
一、用伪代码来表示:跑在独立线程中的循环ui
while(TRUE) {
r = wait();
execute(r);
}
复制代码
二、整个循环作的事情基本上就是反复 等待 - 执行
,这里的执行过程,其实都是一个宏观任务。能够大体理解为:宏观任务的队列就至关于时间循环。spa
三、在宏观任务中,JavaScript
的 Promise
还会产生异步代码
,JavaScript
必须保证这些异步代码在一个宏观任务中完成,所以,每一个宏观任务中又包含了一个微观任务队列:以下图所示线程
例如:Promise
永远在队列尾部添加微观任务。setTimeout
等宿主 API
,则会添加宏观任务。code
JavaScript
语言提供的一种标准化的异步管理
方式,当进行 io、等待或者其它异步操做的函数,不返回真实结果,而返回一个承诺
,函数的调用方能够在合适的时机,选择等待这个承诺兑现
。
function sleep(duration) {
return new Promise(function(resolve, reject) {
setTimeout(resolve,duration);
})
}
sleep(1000).then( ()=> console.log("finished"));
复制代码
Promise
的 then
回调是一个异步
的执行过程。
Promise
函数中的执行顺序var r = new Promise(function(resolve, reject){
console.log("a");
resolve()
});
r.then(() => console.log("c"));
console.log("b")
// 输出顺序:a b c
复制代码
setTimeout
混用的 Promise
var r = new Promise(function(resolve, reject){
console.log("a");
resolve()
});
setTimeout(()=>console.log("d"), 0)
r.then(() => console.log("c"));
console.log("b")
// 输出顺序:a b c d
复制代码
Promise
产生的是 JavaScript
引擎内部的微任务
,而 setTimeout
是浏览器 API
,它产生宏任务
。因此d
一定在 c
以后输出。
1
秒的 Promise
setTimeout(()=>console.log("d"), 0)
var r = new Promise(function(resolve, reject){
resolve()
});
r.then(() => {
var begin = Date.now();
while(Date.now() - begin < 1000);
console.log("c1")
new Promise(function(resolve, reject){
resolve()
}).then(() => console.log("c2"))
});
// 输出顺序:c1 c2 d
复制代码
这个例子很好的解释了微任务优先的原理
。
function sleep(duration) {
return new Promise(function(resolve, reject) {
console.log("b");
setTimeout(resolve,duration);
})
}
console.log("a");
sleep(5000).then(()=>console.log("c"));
// 输出顺序:a b c(c要等5秒)
复制代码
第一个宏观任务中,包含了前后同步执行的 console.log("a")
; 和 console.log("b")
;。
setTimeout
后,第二个宏观任务执行调用了 resolve
,而后 then
中的代码异步获得执行,调用了 console.log("c")
。
async/await
是ES2016
新加入的特性,它提供了用for、if
等代码结构来编写异步的方式,而且运行时基础是Promise
。
一、async
函数是在 function
关键字以前加上 async
关键字,这样就定义了一个 async
函数,能够在其中使用 await
来等待一个 Promise
。
function sleep(duration) {
return new Promise(function(resolve, reject) {
setTimeout(resolve,duration);
})
}
async function foo(){
console.log("a")
await sleep(2000)
console.log("b")
}
foo();
// 输出顺序:a b(b要等两秒)
复制代码
二、async
嵌套
function sleep(duration) {
return new Promise(function(resolve, reject) {
setTimeout(resolve,duration);
})
}
async function foo(name){
await sleep(2000)
console.log(name)
}
async function foo2(){
await foo("a");
await foo("b");
}
foo2();
// 输出顺序:a(a等两秒) b(b也等两秒)
复制代码
看完这篇确实帮我解决了以前困扰个人问题,赞一个。。。明天也要加油鸭。。。。