关于异步任务的一点疑问,有没有老哥帮忙解答下

2023-01-11 10:11:21 +08:00
 yezheyu

假设我需要使用 XMLHttpRequest 下载一张图片,然后展示在网页上。

因为下载图片比较耗时,会阻塞主线程,因此会被放到网络线程中执行。

当网络线程下载完图片后,再把图片对象 img 以参数的形式传到回调函数 showPic(img)中,再把回调函数 showPic 封装为任务放到任务队列中,等待主线程空闲后执行,把图片加载到网页上

我想问下,在异步编程中,对于这种单独起一个线程执行耗时任务,为啥耗时任务执行完的后续收尾代码( showPic )非要放到任务队列中让主线程执行,为啥不干脆在自己的线程中执行。

反正对耗时任务的结果产生依赖的代码都在回调函数中,主线程中代码的执行又不依赖耗时任务的结果

而且万一主线程执行很慢,等图片下载完还没执行结束,那加载图片( showPic )不就被动延后。 而把 showPic 让网络进程执行,不就能在图片下载完后立即被加载出来,也不用管主线程是否执行完

4525 次点击
所在节点    程序员
43 条回复
yezheyu
2023-01-12 18:07:27 +08:00
关于 button 的点击事件的回调函数 this 为啥是 button

我猜是这样的的,你们看对吗?

当页面上一个点击事件触发时,页面上如果有多个元素绑定了点击事件,那总不能把所有的点击事件都触发了,为了精准触发某个按钮的点击事件,所以区别于一般的任务,其多保存了一个回调函数的绑定对象,大概结构类似下面

{
btn1:{
showText1: func(){…},
showText2: func(){…}
}
}

所以回调函数调用时是这样 btn1.showText()调用,走的隐式绑定,所以 this 指向 btn1

@biguokang
@autoxbc
@Al0rid4l
h0099
2023-01-12 19:59:54 +08:00
#40 @Al0rid4l 不过也不是什么很难的东西, 规则就一句话的事
一句话解释 js 的奇妙深刻 this:
函数的闭包作用域是在声明时从声明处的词法作用域向上捕获所有会被函数引用到以及不论是否用到都捕获的 this 的上下文符号集合。对于使用 function()语法声明的函数,允许使用.bind/apply/call(thisArg)来重新定义该函数闭包作用域中的 this 指向,但对于 arrow fun 语法() => {}则不允许(因此 arrow fun 的 this 指向是 immutable 的)

这就像一句话解释 monad:
单子是自函子范畴上的幺半群
一样的正确但又令萌新完全听不懂
如同 https://ex.noerr.eu.org/t/900380
h0099
2023-01-12 20:01:59 +08:00
#41 @yezheyu 阁下又凭什么假定浏览器内部实现这些 dom event 时写的是 js 代码用的是 js object ?
什么又叫“区别于一般的任务”?什么是您所说任务?

我已于#38 解释
> 那为啥 button 点击事件的回调函数中 this 会指向事件的触发对象 button 呢?而不是 window ?

您可以理解为有一个`buttonClickCallback.call(buttomElement, clickEvent)`的 js 被执行
您也可以自己执行这个`.call(buttomElement)`,同样会改变回调(只要不是用 arrow fun 语法声明的)的 this 为 button

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/908083

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX