我最近遇到了一个相当讨厌的错误,其中代码是<select>通过JavaScript动态加载的.这种动态加载<select>具有预先选择的值.在IE6中,我们已经有了修复所选内容的代码<option>,因为有时它<select>的selectedIndex值与所选<option>的index属性不同步,如下所示:
field.selectedIndex = element.index;
Run Code Online (Sandbox Code Playgroud)
但是,此代码无效.即使selectedIndex正确设置了字段,最终也会选择错误的索引.但是,如果我alert()在正确的时间插入声明,则会选择正确的选项.考虑到这可能是某种时间问题,我尝试了一些随机的东西,我之前在代码中看到过:
var wrapFn = (function() {
var myField = field;
var myElement = element;
return function() {
myField.selectedIndex = myElement.index;
}
})();
setTimeout(wrapFn, 0);
Run Code Online (Sandbox Code Playgroud)
这有效!
我已经找到了解决问题的方法,但是我很不安,因为我不知道为什么这会解决我的问题.有人有官方解释吗?使用"稍后"调用我的功能可以避免哪些浏览器问题setTimeout()?
nodejs架构内部有两个事件循环吗?
在I/O请求上,节点将请求排队到libeio,后者又通过使用libev的事件通知数据的可用性,最后这些事件是由v8事件循环使用回调来处理的吗?
基本上,libev和libeio如何集成在nodejs架构中?
有没有可用于提供nodejs内部架构清晰图片的文档?
我在想它,这就是我提出的:
假设我们有这样的代码:
console.clear();
console.log("a");
setTimeout(function(){console.log("b");},1000);
console.log("c");
setTimeout(function(){console.log("d");},0);
Run Code Online (Sandbox Code Playgroud)
请求进来,JS引擎开始逐步执行上面的代码.前两个呼叫是同步呼叫.但是当谈到setTimeout方法时,它就变成了异步执行.但是JS立即从它返回并继续执行,这被称为Non-Blocking或Async.并继续致力于其他等
执行结果如下:
ACDB
所以基本上第二个setTimeout完成第一个,它的回调函数比第一个更早执行,这是有道理的.
我们在这里谈论单线程应用程序.JS引擎继续执行此操作,除非它完成第一个请求,否则它不会进入第二个请求.但好处是它不会等待阻塞操作,比如setTimeout解决所以它会更快,因为它接受新的传入请求.
但我的问题出现在以下几个方面:
#1:如果我们讨论的是单线程应用程序,那么setTimeouts当JS引擎接受更多请求并执行它们时,什么机制会处理?单个线程如何继续处理其他请求?什么工作,setTimeout而其他请求继续进入并执行.
#2:如果这些setTimeout函数在幕后执行,而有更多请求进入和执行,那么在幕后执行异步执行的是什么?我们谈到的这件事叫EventLoop什么?
#3:但是不应该将整个方法放入,EventLoop以便整个事件被执行并调用回调方法?这是我在谈论回调函数时所理解的:
function downloadFile(filePath, callback)
{
blah.downloadFile(filePath);
callback();
}
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,JS引擎如何知道它是否是异步函数,以便它可以将回调EventLoop? Perhaps something like the放在C#中的async`关键字中,或者某种属性指示JS引擎将采用的方法是异步方法并应相应地对待.
#4:但是一篇文章说的与我猜测事情可能如何起作用完全相反:
Event Loop是一个回调函数队列.执行异步函数时,回调函数将被推入队列.在执行异步函数之后的代码之前,JavaScript引擎不会开始处理事件循环.
#5:这里有这个图像可能会有所帮助,但图像中的第一个解释是说第4个问题中提到的完全相同:

所以我的问题是要对上面列出的项目做一些澄清?
我刚刚读完了Promises/A +规范并偶然发现了微任务和macrotask这两个术语:请参阅http://promisesaplus.com/#notes
我以前从未听说过这些术语,现在我很好奇它的区别是什么?
我已经尝试在网上找到一些信息,但我发现的所有内容都来自w3.org档案馆(这并不能解释我与众不同之处):http://lists.w3.org/Archives /Public/public-nextweb/2013Jul/0018.html
另外,我发现了一个名为"macrotask"的npm模块:https://www.npmjs.org/package/macrotask 同样,没有明确区别的是什么.
我所知道的是,它与事件循环有关,如https://html.spec.whatwg.org/multipage/webappapis.html#task-queue 和https://html.spec.whatwg中所述. .ORG /多页/ webappapis.html#执行-A-microtask检查点
根据WHATWG规范,我知道理论上我应该能够自己提取差异.但我确信其他人也可以从专家的简短解释中受益.
let x = 0;
async function test() {
x += await 5;
console.log('x :', x);
}
test();
x += 1;
console.log('x :', x);Run Code Online (Sandbox Code Playgroud)
x记录的值为1和5。我的问题是:为什么x 5第二个日志的值是?
如果test是后执行x += 1(因为它是一个异步函数),那么价值x是1由时间test执行,所以x += await 5应的值x 6。
我已经越来越多地进入node.js体系结构的内部,我看到的一个术语是"tick",如"事件循环的下一个tick"或函数nextTick().
我没有看到的是对什么是"滴答"的确切定义.基于各种文章(例如这篇文章),我已经能够将一个概念拼凑在一起,但我不确定它是多么准确.
我能获得node.js事件循环滴答的精确详细描述吗?
如果你使用过gui工具包,你就知道有一个事件循环/主循环应该在一切完成后执行,这将使应用程序保持活跃并响应不同的事件.例如,对于Qt,您可以在main()中执行此操作:
int main() {
QApplication app(argc, argv);
// init code
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,app.exec()是应用程序的主循环.
实现这种循环的显而易见的方法是:
void exec() {
while (1) {
process_events(); // create a thread for each new event (possibly?)
}
}
Run Code Online (Sandbox Code Playgroud)
但是这会将CPU限制在100%并且实际上是无用的.现在,我如何实现这样一个响应的事件循环,而不必完全占用CPU?
回答在Python和/或C++中受到赞赏.谢谢.
脚注:为了学习,我将实现自己的信号/插槽,我会用它们来生成自定义事件(例如go_forward_event(steps)).但是如果你知道如何手动使用系统事件,我也想知道这一点.
我有一个小的GUI测试,带有"开始"按钮和进度条.期望的行为是:
观察到的行为是"开始"按钮冻结5秒钟,然后显示进度条(无振荡).
到目前为止,这是我的代码:
class GUI:
def __init__(self, master):
self.master = master
self.test_button = Button(self.master, command=self.tb_click)
self.test_button.configure(
text="Start", background="Grey",
padx=50
)
self.test_button.pack(side=TOP)
def progress(self):
self.prog_bar = ttk.Progressbar(
self.master, orient="horizontal",
length=200, mode="indeterminate"
)
self.prog_bar.pack(side=TOP)
def tb_click(self):
self.progress()
self.prog_bar.start()
# Simulate long running process
t = threading.Thread(target=time.sleep, args=(5,))
t.start()
t.join()
self.prog_bar.stop()
root = Tk()
root.title("Test Button")
main_ui = GUI(root)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
基于从布赖恩奥克利的信息在这里,我明白,我需要使用线程.我尝试创建一个线程,但我猜测,因为线程是从主线程中启动的,所以没有用.
我有想法放置在不同的类中的逻辑部分,以及从该类,类似于由A.罗达斯示例代码内实例化GUI 这里.
我的问题:
我无法弄清楚如何编码它,以便这个命令:
self.test_button = Button(self.master, command=self.tb_click)
Run Code Online (Sandbox Code Playgroud)
调用位于另一个类中的函数.这是一件坏事还是可能?我如何创建一个可以处理self.tb_click的第二类?我试着跟随A. Rodas的示例代码,它的工作非常精彩.但是我无法弄清楚如何在触发动作的Button小部件的情况下实现他的解决方案.
如果我应该在单个GUI类中处理线程,那么如何创建一个不干扰主线程的线程呢?
我想在每次执行flask路径时执行异步函数.目前我的abar函数从未执行过.你能告诉我为什么吗?非常感谢你:
import asyncio
from flask import Flask
async def abar(a):
print(a)
loop = asyncio.get_event_loop()
app = Flask(__name__)
@app.route("/")
def notify():
asyncio.ensure_future(abar("abar"), loop=loop)
return "OK"
if __name__ == "__main__":
app.run(debug=False, use_reloader=False)
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)
我也尝试将一个阻塞调用放在一个单独的线程中.但它仍然没有称之为abar功能.
import asyncio
from threading import Thread
from flask import Flask
async def abar(a):
print(a)
app = Flask(__name__)
def start_worker(loop):
asyncio.set_event_loop(loop)
try:
loop.run_forever()
finally:
loop.close()
worker_loop = asyncio.new_event_loop()
worker = Thread(target=start_worker, args=(worker_loop,))
@app.route("/")
def notify():
asyncio.ensure_future(abar("abar"), loop=worker_loop)
return "OK"
if __name__ == "__main__":
worker.start()
app.run(debug=False, use_reloader=False)
Run Code Online (Sandbox Code Playgroud) 我已经制作了一个如何理解它的图表:
current queue,check queue,close callbacks queue,timers queue和I/O callbacks queue.current queue一次只能从一个函数(任务/作业)执行.current queue到自身之后执行,并将macrotasks (任务)添加到check queue.它可以通过要求API执行它来直接向其他队列添加任务.Idle, prepare phase用于某些内部节点js业务(可能像垃圾收集).Poll phase从线程池中轮询线程,并使用适当的回调填充队列.Idle, prepare和poll阶段没有与它们相关的js回调的队列.thread pool都是相同的,没有专业化.current task queue.这种理解是正确的还是我错过了什么?
可以在此处找到带有图表的MS Power Point .pptx文件.
event-loop ×10
javascript ×6
node.js ×5
python ×2
async-await ×1
asynchronous ×1
blocking ×1
c++ ×1
dom ×1
flask ×1
libev ×1
progress-bar ×1
promise ×1
python-3.x ×1
tkinter ×1