一节课彻底弄懂promise、async、await(一)

刚接触js的时候,对于es6的promise、async、await简直怕的要死,甚至有段时间非常害怕promise这个词,随着后面慢慢的接触,觉得这个东西并非那么难理解,主要还是需要弄懂js的一些基础知识。那么接下来,跟上我的思路,一起彻底弄懂promise、async、await。

如果要弄懂promise,就必须弄懂什么是异步、什么是同步,这篇文章主要是讲一下什么是同步、什么是异步。

js是怎么来的?

任何新语言的出现肯定是与他当时的需求有关系的,js全称是Javascript,诞生于1995年(跟我同岁)。
最初他的诞生就是为了表单提交的时候做提示用的,在js问世之前,所有的表单都必须提交到服务端才能校验必填项,
比如你想申请一个qq号,各种信息填了一大堆,提交完才知道,你手机号少输入了一位重新输入,
那肯定砸电脑的心都有了,这个时候,js出生了,因为是跟用户做实时交互的,所以最早叫livescript,
当时为了蹭蹭Java的热度,上户口的时候就改成了Javascript,一不小心长大了可以跟Java平起平坐了。

js为什么是单线程

js从诞生之初就是单线程,那为什么是单线程呢?
为了让我们这些菜鸡更容易入门?当然不是。
js主要的用途就是操作DOM,以及与用户的交互,这就决定了他只能是单线程,
比如你这个线程创建了一个DOM,那个线程给删除了,这时候浏览器应该以哪个为准,
所以这个应该永远不会变,你前端发展的能造火箭了,js肯定也是单线程的。

一、什么是同步和异步

什么是同步呢?
你可以理解为同一个时间,你只能干一件事。今天下班早,你想给女朋友打个电话,女朋友可能跟其他小伙伴一起吃饭呢,
由于手机静音,所以听不到,你就一直打,一直打,啥都没干,把时间都浪费了,这就叫同步。因为js是单线程的嘛,所以js从小就是同步的。

来一段代码:
function second() {
    console.log('second')
}
function first(){
    console.log('first')
    second()
    console.log('Last')
}
first()

这个很简单,执行打印结果:
first、second、last

那么js执行这段代码,到底发生了什么呢?这里面又有一个‘调用栈’的概念

调用栈

是不是一听到什么堆栈就害怕,别慌,没那么复杂,你可以理解为一个厕所,大家去上厕所,但是!不是先进先出,而是后进先出。用调用栈的概念,解释一下上面代码的执行顺序:

当执行此代码时,将创建一个全局执行上下文并将其推到调用堆栈的顶部;// 这个不太重要,下面是重点
first()函数先上,现在他在顶部;
然后打印‘first’,然后执行完了,这个时候这个console.log会自动弹走,就是这个console.log虽然是后进来的,但是他先走了;
现在first函数仍然在顶部,他下面还有second函数,所以不会弹走;
执行second()函数,这时候second函数在顶部;
打印‘second’,然后执行完了,弹走这个console.log,这时候second在顶部;
这个时候second函数的事儿都干完了,他也弹走了,这时候first函数在顶部;
浏览器会问,first你还有事吗,first说我还有一个,执行打印‘last’
什么是异步呢?
电话没打通,你就给女朋友发了个短信,洗澡去了,你回家了告诉我,(等我洗完了)再打给你,这就是异步。
后来为了提高效率,把浏览器的多个内核都用起来,HTML5提出Web Worker标准,
允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。
所以这并没有影响js单线程的本质,js还是每次只能干一件事,只不过把洗澡提前了而已。

来段代码:
const getList = () => {
    setTimeout(() => {
        console.log('我执行了!');
    }, 2000);
};
console.log('Hello World');
getList();
console.log('哈哈哈');

执行顺序是:
Hello World、哈哈哈、我执行了!(两秒以后执行最后一个)

这段代码执行,又发生了什么呢?这个地方又有一个‘消息队列’的概念,不慌!

消息队列

刚才我们说了,同步的时候,浏览器会维护一个‘执行栈’,除了执行栈,在开启多线程的时候,浏览器还会维护一个消息列表,除了主线程,其余的都是副线程,这些副线程合起来就叫消息列表。
我们用消息列表的概念分析一下上面的代码:

按照执行顺序console.log('Hello World')先执行,浏览器一看,中央军(主线程)!你先过;
然后是getlist函数执行,浏览器看到setTimeout,你是八L(副线程)!你先靠边等着;
然后是console.log('哈哈哈')执行,中央军(主线程)!你也过;
然后浏览器问,还有中央军吗?没了,八L开始过!

增加难度:

setTimeout(function() {
    console.log('我是定时器!');
})
new Promise(function(resolve) {
    console.log('我是promise!');
    resolve();
}).then(function() {
    console.log('我是then!');
})
console.log('我是主线程!');

执行顺序:
我是promise!
我是主线程!
我是then!
我是定时器!

为什么promise.then比定时器先执行呢?这个里面又涉及了一个‘事件轮询’的概念。

初识事件轮询

上面我们说了,浏览器为了提升效率,为js开启了一个不太一样的多线程,因为js不能同时执行嘛,那副线程(注意是副线程里面哈)里面谁执行,这个选择的过程,就可以理解为事件轮询。我们先用事件轮询的顺序分析一下上面的代码,再来上概念:

promise函数肯定首先执行,他是主线程嘛,打印‘我是promise’;
然后继续走主线程,打印‘我是主线程’;
然后主线程走完了,开始走消息列表;
(宏任务和微任务一会再讲)
这个时候会先执行promise.then,因为他是微任务,里面的‘我是then!’
消息列表里面在上面的是定时器,但是定时器是宏任务,优先级比较低,所以会往后排;
什么是宏任务?微任务?
**宏任务(Macrotasks):**js同步执行的代码块,setTimeout、setInterval、XMLHttprequest、setImmediate、I/O、UI rendering等。

**微任务(Microtasks):**promise、process.nextTick(node环境)、Object.observe, MutationObserver等。

微任务比宏任务要牛逼一点

浏览器执行的顺序:
(1)执行主代码块,这个主代码块也是宏任务
(2)若遇到Promise,把then之后的内容放进微任务队列
(3)遇到setTimeout,把他放到宏任务里面
(4)一次宏任务执行完成,检查微任务队列有无任务 
(5)有的话执行所有微任务 
(6)执行完毕后,开始下一次宏任务。

那么这个2、3、4、5、6执行的过程就是事件轮询。

可能写了那么多还没有涉及到promise和async、await,但是前面的同步、异步是基础,只有搞懂了同步异步到底是怎么回事,才能有基础去学promise,下一章就来聊聊怎么让同步变异步,异步变同步,哪些地方用到!

在这儿感谢掘金大神的文章,为了表示尊重,挂上地址!

https://juejin.im/post/5e1d0de3e51d455887067f90

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容