假设我这样做:
var timer = setTimeout(function() {
console.log("will this happen?");
}, 5000);
Run Code Online (Sandbox Code Playgroud)
然后在不到5秒后,另一个回调(例如来自NodeJS中的网络事件)触发并清除它:
clearTimeout(timer);
Run Code Online (Sandbox Code Playgroud)
是否有可能来自setTimeout调用的回调已经在此时执行的队列中,如果是这样,clearTimeout是否及时停止它?
为了澄清,我说的是setTimeout时间实际到期并且解释器启动执行它的过程的情况,但是另一个回调当前正在运行,因此消息被添加到队列中.这似乎是那些容易不被考虑的竞争条件类型之一.
基本上我需要在Java中完成同样的事情:
SwingUtilities.invokeLater(()->{/* function */});
Run Code Online (Sandbox Code Playgroud)
或者在javascript中这样:
setTimeout(()=>{/* function */}, 0);
Run Code Online (Sandbox Code Playgroud)
但是用Qt和lambda.所以有些伪代码:
Qt::queuePushMagic([]() { /* function */ });
Run Code Online (Sandbox Code Playgroud)
作为一个额外的复杂性,我需要这个在多线程上下文中工作.我实际上要做的是在正确的线程中自动运行某些方法.那么代码看起来如何:
SomeClass::threadSafeAsyncMethod() {
if(this->thread() != QThread::currentThread()) {
Qt::queuePushMagic([this]()=>{ this->threadSafeAsyncMethod() });
return;
}
}
Run Code Online (Sandbox Code Playgroud)
这该怎么做?
I'm trying to create a function performing some asynchronous operations using asyncio, users of this function should not need to know that asyncio is involved under the hood. I'm having a very hard time understanding how this shall be done with the asyncio API as most functions seem to operate under some global loop-variable accessed with get_event_loop and calls to this are affected by the global state inside this loop.
I have four examples here where two (foo1 and …
该事件循环文档中提到event_loop_policy,但没有描述它是什么,为什么需要将详细介绍这个抽象层。(文档甚至说可以自定义这一层)。
另外,help(asyncio.get_event_loop_policy())只是说...
带有子进程观察器的 UNIX 事件循环策略。
然后,我就更糊涂了。什么是watcher?什么是child processes中event loop?
大多数解释浏览器中 JavaScript 并发模型的示例都列出了三个部分:调用堆栈、Web API 和事件队列。通常描述的正常过程是 Web API 不由核心 ECMAScript 处理,而是由 Web API 处理;此时它们会移入事件队列等待,直到调用堆栈为空才能执行。setTimeout通常用作此过程的示例。
我的问题是:
1.)既然console.log是一个Web API,为什么它不进入setTimeout后面的事件队列?(它是否进入事件队列)?
2.) 如果它不进入事件队列,那么什么决定了哪些 API 从调用堆栈中拉出以经历事件循环过程?是不是只有那些等待某些东西并且有回调的API?
setTimeout(function(){
doSomething();
},0);
console.log('Hello World!');
Run Code Online (Sandbox Code Playgroud) 我有一个简单的 Flask API,其中一个端点调用另一个文件中的方法,以使用 request-html 从站点呈现一些 javascript
@app.route('/renderJavascript')
def get_attributes():
return get_item_attributes('https://www.site.com.mx/site.html')
Run Code Online (Sandbox Code Playgroud)
该方法的代码如下所示:
from requests_html import HTMLSession
from bs4 import BeautifulSoup
def get_item_attributes(url):
#Connecting to site.
session = HTMLSession()
resp = session.get(url)
resp.html.render()
resp.session.close()
soup = BeautifulSoup(resp.html.html,'lxml')
................................
#Rest of the code is handling the data with bs4 and returning a json.
Run Code Online (Sandbox Code Playgroud)
调用端点后,我收到此错误:
Traceback (most recent call last):
File "C:\Python37\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python37\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python37\lib\site-packages\flask\app.py", line 1820, in …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关节点的事件循环阶段的内容,并说
- 计时器:此阶段执行由 setTimeout() 和 setInterval() 安排的回调。
- 挂起的回调:执行推迟到下一个循环迭代的 I/O 回调。
- 空闲,准备:仅内部使用。
- poll:检索新的I/O事件;执行 I/O 相关回调(几乎所有回调,关闭回调、计时器调度的回调和 setImmediate() 除外);节点会在适当的时候阻塞在这里。
- check:setImmediate() 回调在这里被调用。
- 关闭回调:一些关闭回调,例如socket.on('close', ...)。
所以这里我有一个简单的代码来测试上面的一些阶段。当您执行代码时,您会得到以下输出:
但根据文档,套接字回调是阶段的最后一个。为什么先执行呢?
let socket = require("net").createServer();
socket.on("data", function (data) {
console.log(data.toString());
});
socket.on("close", function (data) {
console.log("close");
});
socket.listen(8080);
const fs = require("fs");
fs.readFile("readme.txt", () => {
socket.close();
setTimeout(() => {
console.log("timeout");
}, 0);
setImmediate(() => {
console.log("immediate");
});
});
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个执行可中断计算的网络工作者。Worker.terminate()我知道这样做的唯一方法(除了)是定期让步给消息循环,以便它可以检查是否有任何新消息。例如,这个网络工作者计算从 0 到 的整数之和data,但是如果您在计算过程中向它发送一条新消息,它将取消计算并开始新的计算。
let currentTask = {
cancelled: false,
}
onmessage = event => {
// Cancel the current task if there is one.
currentTask.cancelled = true;
// Make a new task (this takes advantage of objects being references in Javascript).
currentTask = {
cancelled: false,
};
performComputation(currentTask, event.data);
}
// Wait for setTimeout(0) to complete, so that the event loop can receive any pending messages.
function yieldToMacrotasks() {
return new Promise((resolve) => setTimeout(resolve));
} …Run Code Online (Sandbox Code Playgroud) 我尝试理解 javascript 的事件循环,但我对fetch.
console.log("1")
Promise.resolve(2)
.then(data => { console.log(data) })
console.log("3")
Run Code Online (Sandbox Code Playgroud)
上面的代码执行结果为:1,3,2。由于在第一个事件循环中,引擎执行日志1,解析2,将then块放入微任务队列,日志3,然后搜索微任务队列并执行日志数据。
console.log("1")
fetch("some-url")
.then(data => { console.log(data) })
console.log("3")
Run Code Online (Sandbox Code Playgroud)
引擎执行完log 1之后,做了什么?它会立即执行 HTTP 请求吗?如果是,它会将then块放入微任务队列吗?我认为它可能不会将then块放入微任务队列,因为当当前队列为空且引擎开始获取微任务队列时,它获取的数据可能尚未准备好。那么thenblock是如何进入微任务队列的呢?引擎是否会向内核回调,告诉它then在响应准备好时将块放入微任务队列中?
如果问题在浏览器和 Node.js 中不同,我更喜欢浏览器答案。
在一些关于 JavaScript 异步行为的在线资源中,还提到了浏览器架构、调用堆栈、事件循环和事件队列等概念。在描述浏览器事件循环的工作原理时,有些人使用“事件队列”一词,而另一些人则使用“回调队列”。我对这些术语感到困惑,想知道它们是否指的是浏览器中使用的相同队列数据结构,或者它们是否不同并用于处理不同的场景?
图1 -
图2-
event-loop ×10
javascript ×5
python ×3
node.js ×2
settimeout ×2
asynchronous ×1
c++ ×1
callback ×1
dom-events ×1
ecmascript-6 ×1
flask ×1
lambda ×1
python-3.5 ×1
python-3.x ×1
qt ×1
qthread ×1
v8 ×1
web-worker ×1