Skip to content

Commit 023329c

Browse files
committed
update
1 parent fd6b3b0 commit 023329c

File tree

6 files changed

+99
-9
lines changed

6 files changed

+99
-9
lines changed

.vuepress/header.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1514,7 +1514,7 @@
15141514
],
15151515
[
15161516
"js/221",
1517-
"请简述一下 event loop"
1517+
"请简述一下 event loop⭐️"
15181518
],
15191519
[
15201520
"js/229",

.vuepress/issues.json

+14-4
Original file line numberDiff line numberDiff line change
@@ -4639,7 +4639,17 @@
46394639
"name": "js"
46404640
}
46414641
],
4642-
"comment": ""
4642+
"comment": {
4643+
"id": "MDEyOklzc3VlQ29tbWVudDc4Njk5MDU2Ng==",
4644+
"body": "![image](https://user-images.githubusercontent.com/19162008/109372242-850c0980-78e3-11eb-8fe6-ecb15fa5e480.png)\r\n\r\nheap(堆):对象被分配在堆中,堆是一个用来表示一大块(通常是非结构化的)内存区域的计算机术语。\r\nstack(栈):函数调用形成了一个由若干帧组成的栈。\r\nWebAPIS:囊括 Web 强大脚本能力的每个 API 参考资料, 包括 DOM 、所有相关的 APIs 及可以用来构建 Web 的相关接口。\r\n队列(event queue || Callback Queue):一个 JavaScript 运行时包含了一个待处理消息的消息队列。每一个消息都关联着一个用以处理这个消息的回调函数\r\n\r\n\r\n[event loop 运行图解](http://latentflip.com/loupe/?code=c2V0VGltZW91dChmdW5jdGlvbigpewogICAgY29uc29sZS5sb2coJzEnKQp9LDApOwoKbmV3oCBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpewoKoCBjb25zb2xlLmxvZygnMicpOwoKoCByZXNvbHZlKCk7Cgp9KS50aGVuKGZ1bmN0aW9uKCl7Cgpjb25zb2xlLmxvZygnMycpCgp9KTsKCmNvbnNvbGUubG9nKCc0Jyk7Cg%3D%3D!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D)\r\n\r\n```\r\nsetTimeout(() => {\r\n console.log(1)\r\n}, 100)\r\nconsole.log(2);\r\nsetTimeout(() => {\r\n console.log(3)\r\n}, 0)\r\n// 2\r\n// 1\r\n// 3\r\n```\r\n\r\n![未标题-1](https://user-images.githubusercontent.com/19162008/109375818-9c0a2600-78fa-11eb-8a0f-1d65394fb6a6.gif)\r\n\r\n\r\n\r\n看图我们可以了解到,setTimeout(() => {console.log(1)}, 0) 会在Stack执行,在放入WebAPIs中当成一个匿名函数执行,匿名函数执行完毕之后会放入Callback Queue 中。\r\nconsole.log(2) 则直接被推入Stack 中执行。\r\n\r\nsetTimeout(() => {console.log(3)}, 0) 同样的执行后放入WebAPIs中当成一个匿名函数执行,在放入Callback Queue中。当同步任务执行完之后,才会将Callback Queue 队列中的方法推入Stack中。\r\n\r\n**因为JS是单线程的,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。为了解决排除等待问题,JS的任务分为同步任务(synchronous)和异步任务(asynchronous)。\r\n所有同步任务都在主线程上执行,形成一个Stac)。异步任务(如果是WebAPI 则会进入WebAPI,例如ajax setTimeout)不进入主线程,而是进入另一 Callback Queue。同步任务顺序执行,只有执行栈中的同步任务执行完了,系统才回读取任务队列中可以执行的异步任务,才会把此异步任务从事件队列中放入执行栈中执行,如此循环,直至所有任务执行完毕。**\r\n\r\n**这就是EventLoop**\r\n\r\n\r\n",
4645+
"reactions": {
4646+
"totalCount": 0
4647+
},
4648+
"author": {
4649+
"login": "martin-yin",
4650+
"url": "https://github.com/martin-yin"
4651+
}
4652+
}
46434653
},
46444654
{
46454655
"id": "MDU6SXNzdWU1NzU5MzgwOTU=",
@@ -7995,7 +8005,7 @@
79958005
],
79968006
"comment": {
79978007
"id": "MDEyOklzc3VlQ29tbWVudDY3NTUxOTA0NQ==",
7998-
"body": "简单实现如下:\r\n\r\n``` js\r\nfunction once (f) {\r\n let result\r\n let revoked = false\r\n \r\n return (...args) => {\r\n if (revoked) return result\r\n const r = f(...args)\r\n revoked = true\r\n result = r\r\n return r\r\n }\r\n}\r\n```\r\n\r\n``` js\r\n> const f = () => {console.log('call'); return 3;}\r\n< undefined\r\n\r\n> once_f = once(f)\r\n< (...args) => {\r\n if (revoked) return result\r\n const r = f(...args)\r\n revoked = true\r\n result = r\r\n }\r\n\r\n// 第一次调用\r\n> once_f()\r\n< call\r\n< 3\r\n\r\n// 第二次调用,没有打印 call\r\n> once_f()\r\n< 3\r\n```",
8008+
"body": "简单实现如下:\r\n\r\n``` js\r\nfunction once (f) {\r\n let result\r\n let revoked = false\r\n \r\n return (...args) => {\r\n if (revoked) return result\r\n const r = f(...args)\r\n revoked = true\r\n result = r\r\n return r\r\n }\r\n}\r\n```\r\n\r\n测试一下\r\n\r\n``` js\r\n> const f = () => {console.log('call'); return 3;}\r\n< undefined\r\n\r\n> once_f = once(f)\r\n< (...args) => {\r\n if (revoked) return result\r\n const r = f(...args)\r\n revoked = true\r\n result = r\r\n }\r\n\r\n// 第一次调用\r\n> once_f()\r\n< call\r\n< 3\r\n\r\n// 第二次调用,没有打印 call\r\n> once_f()\r\n< 3\r\n```\r\n\r\n[once](https://npm.devtool.tech/once) 是社区使用最广泛的一个库,代码实现与上大同小异,然而每月下载量可达上亿,比 vue/react/angular 三者一个月的下载量加起来还要高一倍",
79998009
"reactions": {
80008010
"totalCount": 0
80018011
},
@@ -9397,7 +9407,7 @@
93979407
],
93989408
"comment": {
93999409
"id": "MDEyOklzc3VlQ29tbWVudDc2OTczMzExOQ==",
9400-
"body": "使用 Grid 布局可以轻松解决这个问题:\r\n\r\n``` html\r\n<div class=\"container\">\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n</div>\r\n```\r\n\r\n``` css\r\n@media (min-width: 1024px) {\r\n .container {\r\n grid-template-columns: repeat(3,minmax(0,1fr));\r\n }\r\n}\r\n\r\n@media (min-width: 768px) {\r\n .container {\r\n grid-template-columns: repeat(2,minmax(0,1fr));\r\n }\r\n}\r\n\r\n.conainer {\r\n display: grid;\r\n grid-gap: 1rem;\r\n gap: 1rem;\r\n}\r\n```\r\n\r\n``` html\r\n<div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\"></div>\r\n```",
9410+
"body": "页面布局元素如下,item 数量不固定\r\n\r\n``` html\r\n<div class=\"container\">\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n <div class=\"item\"></div>\r\n</div>\r\n```\r\n\r\n使用 Grid 布局可以轻松解决这个问题,如若使用其它方案,控制好等分的同时再控制好间距也是一个十分头疼的问题:\r\n\r\n1. `grid-template-columns`: 控制等分\r\n2. `gap`: 控制间隙\r\n\r\n``` css\r\n@media (min-width: 1024px) {\r\n .container {\r\n grid-template-columns: repeat(3,minmax(0,1fr));\r\n }\r\n}\r\n\r\n@media (min-width: 768px) {\r\n .container {\r\n grid-template-columns: repeat(2,minmax(0,1fr));\r\n }\r\n}\r\n\r\n.conainer {\r\n display: grid;\r\n gap: 1rem;\r\n}\r\n```\r\n\r\n`TailwindCSS` 是一款非常方便的 CSS 原子类框架,只需要一行即可搞定\r\n\r\n``` html\r\n<div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\"></div>\r\n```",
94019411
"reactions": {
94029412
"totalCount": 0
94039413
},
@@ -9639,7 +9649,7 @@
96399649
],
96409650
"comment": {
96419651
"id": "MDEyOklzc3VlQ29tbWVudDc4MzgzMTgyNw==",
9642-
"body": "``` js\r\nconst content = await new Response(file).text()\r\n```",
9652+
"body": "``` html\r\n<input type=\"file\" id=\"input\" onchange=\"handleFiles(this.files)\">\r\n```\r\n\r\n在浏览器中,通过 `input[type=file]` 来点击上传文件,此时监听 `onChange` 事件,可以获取到 `File` 对象,其中从中可以读取文件内容\r\n\r\n而读取文件内容,需要转化 `File/Blob` 到 `Text`,一般使用以下两种方案\r\n\r\n## FileReader API\r\n\r\n这是最常用处理上传文件的 API,但是却繁琐冗余难记,每次使用基本上都要查文档!\r\n\r\n`FileReader API` 用以读取 File/Blob 内容,正因为繁琐难记,以下实现一个 `readBlob` 函数读取内容。\r\n\r\n``` js\r\nfunction readBlob (blob) {\r\n return new Promise(resolve => {\r\n const reader = new FileReader()\r\n reader.onload = function (e) {\r\n resolve(e.target.result) \r\n }\r\n reader.readAsText(blob)\r\n })\r\n}\r\n```\r\n\r\n## Response API\r\n\r\n而是用 `Response API` 只需要一行内容\r\n\r\n``` js\r\nconst readBlob = (blob) => new Response(blob).text()\r\n```",
96439653
"reactions": {
96449654
"totalCount": 0
96459655
},

fe/css/473.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
回答者: [shfshanyue](https://github.com/shfshanyue)
1111
:::
1212

13-
使用 Grid 布局可以轻松解决这个问题:
13+
页面布局元素如下,item 数量不固定
1414

1515
``` html
1616
<div class="container">
@@ -23,6 +23,11 @@
2323
</div>
2424
```
2525

26+
使用 Grid 布局可以轻松解决这个问题,如若使用其它方案,控制好等分的同时再控制好间距也是一个十分头疼的问题:
27+
28+
1. `grid-template-columns`: 控制等分
29+
2. `gap`: 控制间隙
30+
2631
``` css
2732
@media (min-width: 1024px) {
2833
.container {
@@ -38,11 +43,12 @@
3843

3944
.conainer {
4045
display: grid;
41-
grid-gap: 1rem;
4246
gap: 1rem;
4347
}
4448
```
4549

50+
`TailwindCSS` 是一款非常方便的 CSS 原子类框架,只需要一行即可搞定
51+
4652
``` html
4753
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"></div>
4854
```

fe/js/221.md

+40
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,45 @@
66
欢迎在 Issue 中交流与讨论: [Issue 221](https://github.com/shfshanyue/Daily-Question/issues/221)
77
:::
88

9+
::: tip Author
10+
回答者: [martin-yin](https://github.com/martin-yin)
11+
:::
12+
13+
![image](https://user-images.githubusercontent.com/19162008/109372242-850c0980-78e3-11eb-8fe6-ecb15fa5e480.png)
14+
15+
heap(堆):对象被分配在堆中,堆是一个用来表示一大块(通常是非结构化的)内存区域的计算机术语。
16+
stack(栈):函数调用形成了一个由若干帧组成的栈。
17+
WebAPIS:囊括 Web 强大脚本能力的每个 API 参考资料, 包括 DOM 、所有相关的 APIs 及可以用来构建 Web 的相关接口。
18+
队列(event queue || Callback Queue):一个 JavaScript 运行时包含了一个待处理消息的消息队列。每一个消息都关联着一个用以处理这个消息的回调函数
19+
20+
21+
[event loop 运行图解](http://latentflip.com/loupe/?code=c2V0VGltZW91dChmdW5jdGlvbigpewogICAgY29uc29sZS5sb2coJzEnKQp9LDApOwoKbmV3oCBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpewoKoCBjb25zb2xlLmxvZygnMicpOwoKoCByZXNvbHZlKCk7Cgp9KS50aGVuKGZ1bmN0aW9uKCl7Cgpjb25zb2xlLmxvZygnMycpCgp9KTsKCmNvbnNvbGUubG9nKCc0Jyk7Cg%3D%3D!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D)
22+
23+
```
24+
setTimeout(() => {
25+
console.log(1)
26+
}, 100)
27+
console.log(2);
28+
setTimeout(() => {
29+
console.log(3)
30+
}, 0)
31+
// 2
32+
// 1
33+
// 3
34+
```
35+
36+
![未标题-1](https://user-images.githubusercontent.com/19162008/109375818-9c0a2600-78fa-11eb-8a0f-1d65394fb6a6.gif)
37+
38+
39+
40+
看图我们可以了解到,setTimeout(() => {console.log(1)}, 0) 会在Stack执行,在放入WebAPIs中当成一个匿名函数执行,匿名函数执行完毕之后会放入Callback Queue 中。
41+
console.log(2) 则直接被推入Stack 中执行。
42+
43+
setTimeout(() => {console.log(3)}, 0) 同样的执行后放入WebAPIs中当成一个匿名函数执行,在放入Callback Queue中。当同步任务执行完之后,才会将Callback Queue 队列中的方法推入Stack中。
44+
45+
**因为JS是单线程的,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。为了解决排除等待问题,JS的任务分为同步任务(synchronous)和异步任务(asynchronous)。
46+
所有同步任务都在主线程上执行,形成一个Stac)。异步任务(如果是WebAPI 则会进入WebAPI,例如ajax setTimeout)不进入主线程,而是进入另一 Callback Queue。同步任务顺序执行,只有执行栈中的同步任务执行完了,系统才回读取任务队列中可以执行的异步任务,才会把此异步任务从事件队列中放入执行栈中执行,如此循环,直至所有任务执行完毕。**
47+
48+
**这就是EventLoop**
949

1050

fe/js/406.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ function once (f) {
2727
}
2828
```
2929

30+
测试一下
31+
3032
``` js
3133
> const f = () => {console.log('call'); return 3;}
3234
< undefined
@@ -47,4 +49,6 @@ function once (f) {
4749
// 第二次调用,没有打印 call
4850
> once_f()
4951
< 3
50-
```
52+
```
53+
54+
[once](https://npm.devtool.tech/once) 是社区使用最广泛的一个库,代码实现与上大同小异,然而每月下载量可达上亿,比 vue/react/angular 三者一个月的下载量加起来还要高一倍

fe/js/487.md

+31-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,36 @@
1010
回答者: [shfshanyue](https://github.com/shfshanyue)
1111
:::
1212

13+
``` html
14+
<input type="file" id="input" onchange="handleFiles(this.files)">
15+
```
16+
17+
在浏览器中,通过 `input[type=file]` 来点击上传文件,此时监听 `onChange` 事件,可以获取到 `File` 对象,其中从中可以读取文件内容
18+
19+
而读取文件内容,需要转化 `File/Blob``Text`,一般使用以下两种方案
20+
21+
## FileReader API
22+
23+
这是最常用处理上传文件的 API,但是却繁琐冗余难记,每次使用基本上都要查文档!
24+
25+
`FileReader API` 用以读取 File/Blob 内容,正因为繁琐难记,以下实现一个 `readBlob` 函数读取内容。
26+
27+
``` js
28+
function readBlob (blob) {
29+
return new Promise(resolve => {
30+
const reader = new FileReader()
31+
reader.onload = function (e) {
32+
resolve(e.target.result)
33+
}
34+
reader.readAsText(blob)
35+
})
36+
}
37+
```
38+
39+
## Response API
40+
41+
而是用 `Response API` 只需要一行内容
42+
1343
``` js
14-
const content = await new Response(file).text()
44+
const readBlob = (blob) => new Response(blob).text()
1545
```

0 commit comments

Comments
 (0)