我遇到了一个非常奇怪的问题,即等待已将Promise传递resolve
给事件-发射器回调的Promise会无错误地退出该过程。
const {EventEmitter} = require('events');
async function main() {
console.log("entry");
let ev = new EventEmitter();
let task = new Promise(resolve=>{
ev.once("next", function(){resolve()}); console.log("added listener");
});
await task;
console.log("exit");
}
main()
.then(()=>console.log("exit"))
.catch(console.log);
process.on("uncaughtException", (e)=>console.log(e));
我希望运行此程序时该过程将停止,因为当前显然从未发出过“ next”。但是我得到的输出是:
条目
添加了侦听器
然后nodejs进程正常终止。
我认为这是什么做的垃圾收集器,但ev
并task
显然还是在范围main
。因此,我对如何完全退出该过程而没有错误感到无所适从。
很显然,我 会 最终发出的事件,但我已经简化我的代码上面的重现。我在node v8.7.0
。我的代码有问题吗?或者这是节点错误?
这个问题基本上是:节点如何决定退出事件循环还是再次发生?
基本上,节点保留已调度的异步请求(例如setTimeouts
网络请求等)的参考计数。每调度一次,该计数就会增加,而每完成一次,该计数就会减少。如果到达事件循环周期的末尾,并且引用计数为零,则退出节点。
简单地创建一个Promise或事件发射器并 不会 增加引用计数-
创建这些对象实际上并不是异步操作。例如,此promise的状态将始终处于待处理状态,但过程将立即退出:
const p = new Promise( resolve => {
if(false) resolve()
})
p.then(console.log)
同样,在创建发射器并注册侦听器之后,这也会退出:
const ev = new EventEmitter()
ev.on("event", (e) => console.log("event:", e))
如果您希望Node等待从未计划的事件,那么您可能会想到Node不知道将来是否可能发生事件,但是这样做是因为每次计划一个事件时都会计数。
因此,请考虑以下小改动:
const ev = new EventEmitter()
ev.on("event", (e) => console.log("event:", e))
const timer = setTimeout(() => ev.emit("event", "fired!"), 1000)
// ref count is not zero, event loop will go again.
// after timer fires ref count goes back to zero and node exits
作为附带说明,您可以使用以下命令删除对计时器的引用timeout.unref()
。与前面的示例不同,这将立即退出:
const ev = new EventEmitter()
ev.on("event", (e) => console.log("event:", e))
const timer = setTimeout(() => ev.emit("event", "fired!"), 1000)
timer.unref()
问题内容: 我读到用关键字标记的异步函数隐式返回一个promise: 但这不连贯…假设返回一个诺言,而await关键字将从诺言中返回值,而不是诺言itsef,那么我的getVal函数 应该 返回该值,而不是隐式诺言。 那到底是什么情况?用async关键字标记的函数是隐式返回promise还是控制它们返回的内容? 也许,如果我们不明确地返回某些东西,那么他们会隐式地返回一个诺言…? 更清楚地说,上述
我忙于处理一些以意想不到的方式(对我)响应的代码。它涉及处理Node.jspromise异常。 我修改了下面的函数,这样它所做的就是失败 当我试图调用它并处理这个错误时,问题就出现了。如果我做了下面的事情,它会像我期望的那样工作,函数会失败,并执行返回的捕获,停止最后一个控制台日志的执行 尽管如此,如果我按照如下方式编写函数,它似乎不会返回,它仍然会执行最后一个控制台日志,而不考虑等待时间 如果这
问题内容: 因此,我遇到了多个未知长度的promise链的情况。我希望在处理所有链条后执行一些操作。那有可能吗?这是一个例子: 在此示例中,我设置了一个承诺1,,2和3,这些承诺会在某个随机时间得到解决。然后,我将诺言添加到第一和第三的结尾。我想在所有链条都解决后解决。这是运行此代码时的输出: 有没有办法等待连锁解决? 问题答案: 当所有链条都解决后,我希望所有人解决。 当然,然后将每个链的承诺传
本文向大家介绍承诺回调和异步/等待,包括了承诺回调和异步/等待的使用技巧和注意事项,需要的朋友参考一下 首先,我们必须了解两个主要概念 同步编程 异步编程 同步编程 它等待每个语句完成执行,然后再转到下一条语句。 如果语句不相互依赖,但是由于它们在队列中,它们仍在等待执行,则此方法可能会减慢应用程序的速度。 异步编程 在移动到下一条语句之前,它不等待当前语句完成执行。例如,调用Web服务并使用Ja
问题内容: 我有这样的代码: 我的问题是,节点在运行时立即终止。它显示“ Icanhasclient”,但没有调用回调内的console.log。 (本例中的mysql是node- mysql 。 有什么办法可以使node.js在退出之前等待回调完成? 问题答案: 回调未排队 节点运行直到所有事件 队列 都为空。诸如以下的调用时,回调将添加到事件 队列 中 已执行。该调用是模块开发人员编写的代码的
问题内容: 我对节点还很陌生,我刚刚了解了javascript中提供的async和await函数。我正在尝试在下面随附的代码段中实现此方法。以我的理解,数据库响应应该首先打印到控制台,然后“完成”,但是我无法使其正常工作。任何帮助将不胜感激。 也请尝试说明您所做的修复操作,因为我想了解我做错了什么。 问题答案: 您的函数中没有语句。 通常,这将导致函数返回,但是由于您声明了它,因此它导致其返回 立