我首先尝试了对问题的一般描述,然后更详细地说明为什么通常的方法不起作用.如果你想阅读这些抽象的解释继续下去.最后,我解释了更大的问题和具体的应用程序,所以如果你想阅读它,请跳转到"实际应用程序".
我正在使用node.js子进程来完成一些计算密集型工作.父进程执行它的工作但在执行中的某个时刻它到达了一个点,在继续之前它必须具有来自子进程的信息.因此,我正在寻找一种等待子进程完成的方法.
我目前的设置看起来像这样:
importantDataCalculator = fork("./runtime");
importantDataCalculator.on("message", function (msg) {
if (msg.type === "result") {
importantData = msg.data;
} else if (msg.type === "error") {
importantData = null;
} else {
throw new Error("Unknown message from dataGenerator!");
}
});
Run Code Online (Sandbox Code Playgroud)
和其他地方
function getImportantData() {
while (importantData === undefined) {
// wait for the importantDataGenerator to finish
}
if (importantData === null) {
throw new Error("Data could not be generated.");
} else {
// we should have a proper data now
return …Run Code Online (Sandbox Code Playgroud) 我想使用Python 3 asyncio模块来创建服务器应用程序.我使用主事件循环来监听网络,当收到新数据时,它会进行一些计算并将结果发送给客户端."做一些计算"是否需要新的事件循环?或者它可以使用主事件循环?
我很好奇Event Loop和Promise之间的关系.
该演示揭示了这个问题.我希望它p1 fulfilled出现在中间,因为它们将任务排队到同一个任务队列并逐个执行.
var p1 = new Promise(function(resolve, reject){
resolve(1)
})
setTimeout(function(){
console.log("will be executed at the top of the next Event Loop")
},0)
p1.then(function(value){
console.log("p1 fulfilled")
})
setTimeout(function(){
console.log("will be executed at the bottom of the next Event Loop")
},0)
Run Code Online (Sandbox Code Playgroud)
控制台结果是:
p1 fulfilled
will be executed at the top of the next Event Loop
will be executed at the bottom of the next Event Loop
Run Code Online (Sandbox Code Playgroud)
可视化效果显示promise.then回调没有进入事件循环的任务队列.这是正确的?
【注意:问题与Promise vs setTimeout不一样,因为它更关注Event Loop和Promise之间的关系】
我想知道事件循环如何在javascript中工作,我使用的是node.js,但我想同样的问题适用于浏览器.
我有一些异步调用(让我们说setTimeout或$.ajax或fs.readFile),一段时间后事件循环执行callback
现在当callback被执行时,幕后发生了什么?它是否会恢复它在调用异步内容时使用的堆栈?
在实践中,回调所处的背景是什么?它是如何工作的?
编辑:谢谢,我看到......还有一个问题,事件循环如何"记住"回调的范围?
首先,我是尝试了解什么是Node.Js. 我有两个问题.
第一个问题
从Felix 的文章中,它说"在同一时间只能有一个回调触发.在回调完成执行之前,所有其他回调都必须排队".
然后,考虑以下代码(从nodejs官方网站复制)
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
Run Code Online (Sandbox Code Playgroud)
如果同时收到两个客户端请求,则表示以下工作流程:
我对吗?如果我是对的,如果在很短的时间内有数千个客户端请求,Node.js如何控制.
第二个问题
术语"事件循环"主要用于Node.js主题.我已经明白"事件循环"从下面的http://www.wisegeek.com/what-is-an-event-loop.htm ;
事件循环 - 或主循环,是程序中的一个构造,用于控制和分派初始事件后的事件.
初始事件可以是任何东西,包括按下键盘上的按钮或单击程序上的按钮(在Node.js中,我认为初始事件将是http请求,数据库查询或I/O文件访问).
这称为循环,不是因为事件循环并且连续发生,而是因为循环准备事件,检查事件,调度事件并重新重复该过程.
我对第二段有冲突,特别是" 重复这个过程 "这句话.我接受上面的问题上面的http.createServer代码绝对是"事件循环",因为它反复监听http请求事件.
但我不知道如何识别以下代码,无论是事件驱动还是事件循环.除了在db查询完成后触发的回调函数之外,它不会重复任何操作.
database.query("SELECT * FROM table", function(rows) {
var result = rows;
});
Run Code Online (Sandbox Code Playgroud)
请让我听听你的意见和答案.
有没有办法可以在事件循环中为Node.js任务应用优先级.我想为nodejs的事件循环中存在的任务分配优先级.
假设在事件循环中有5个具有相同优先级的作业A,B,C,D,E,然后接收下一个优先级高于后五个作业的作业.然后事件循环开始执行该更高优先级的作业.
我在使用时遇到了一些问题,QThreads这让我在找到合适的组合之前探索了不同的组合.但是,当涉及事件循环和信号槽处理时,我仍然不完全理解下面显示的四种情况中发生的事情.
我在OUTPUT部分添加了一些注释,但正如您所看到的,我不确定我对观察到的行为的原因是否正确.此外,我不确定是否case 3可以在实际代码中使用.这是我的测试代码(main.cpp每种情况只有不同):
worker.h:
#include <QObject>
#include <QDebug>
#include <QThread>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = 0) { this->isRunning_ = false;}
bool isRunning() const { return isRunning_; }
signals:
void processingFinished();
void inProgress();
public slots:
void process()
{
this->isRunning_ = true;
qDebug() << this << "processing started";
for (int i = 0; i < 5; i++)
{
QThread::usleep(1000);
emit this->inProgress();
}
qDebug() << this << "processing finished";
this->isRunning_ …Run Code Online (Sandbox Code Playgroud) 因此,最近我一直在阅读有关Javascript承诺的教程。
这是一个示例,用于解释宏任务队列(即事件循环)和微任务队列。
let promise = Promise.reject(new Error("Promise Failed!"));
promise.catch(err => alert('caught'));
// no error, all quiet
window.addEventListener('unhandledrejection', event => alert(event.reason));
Run Code Online (Sandbox Code Playgroud)
它说,因为promise.catch捕获错误,所以最后一行,所以事件处理程序永远不会运行。我能理解 但是随后他稍微调整了这个示例。
let promise = Promise.reject(new Error("Promise Failed!"));
setTimeout(() => promise.catch(err => alert('caught')));
// Error: Promise Failed!
window.addEventListener('unhandledrejection', event => alert(event.reason));
Run Code Online (Sandbox Code Playgroud)
这一次,他说,事件处理程序会首先运行,并捕获错误并经过这个promise.catch最终捕获错误。
对于第二个示例,我不了解的是,为什么事件处理程序在promise.catch?之前运行?
我的理解是
setTimeout,将其放在宏任务队列中,然后,因为微任务比宏任务具有更高的优先级。我们首先兑现诺言。之后,我们将宏任务队列中的第一个任务出队setTimeout。因此,根据我的理解,该错误应由内部函数捕获setTimeout。
请纠正我。
The following quotes are my primary references for understanding microtask queue processing:
Microtasks (which promises use) are processed when the JS stack empties.
That doesn't make sense to me.
One go-around of the event loop will have exactly one task being processed from the macrotask queue (this queue is simply called the task queue in the WHATWG specification). After this macrotask has finished, all available microtasks will be processed, namely within the same go-around cycle.
- Stack …
最好编写不依赖于即时回调的时间的代码(如微任务与宏任务),但让我们暂时将其搁置一旁。
setTimeout将一个宏任务排队,它至少要等到所有微任务(以及它们产生的微任务)完成后才开始。下面是一个例子:
console.log('Macrotask queued');
setTimeout(function() {
console.log('Macrotask running');
});
Promise.resolve()
.then(function() {
console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');Run Code Online (Sandbox Code Playgroud)
a.then在已解决的 Promise 上的行为与立即setTimeout回调的行为有根本的不同——Promise.then将首先运行,即使Promise 已先setTimeout排队。但只有现代浏览器支持 Promises。如果微任务的特殊功能Promise不存在,如何正确填充它?
如果您尝试使用 模仿.then的微setTimeout任务,您将排队一个宏任务,而不是一个微任务,因此.then如果宏任务已经排队,那么糟糕的polyfill将不会在正确的时间运行。
有一个使用 的解决方案MutationObserver,但它看起来很难看,而且不是MutationObserver用来做什么的。此外,MutationObserver在 IE10 及更早版本上不支持。如果想要在原生不支持 Promises 的环境中排队一个微任务,有没有更好的选择?
(我实际上并不是在尝试支持 IE10 - 这只是关于微任务如何在没有 Promise 的情况下排队的理论练习)
event-loop ×10
javascript ×6
node.js ×4
promise ×3
asynchronous ×1
browser ×1
c++ ×1
python ×1
python-3.4 ×1
qt ×1
theory ×1
this ×1