为什么我的控制台记录:`TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer`
Why is my console logging: `TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer`
我正在学习课程 stream-adventure。其中一项任务是制作一个将所有请求转换为大写的 http 服务器,并在响应中 return 它。
现在我设法让它工作并且作业通过了。但是,控制台给了我一个 TimeoutOverflowWarning。
(node:15710) TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer.
Timer duration was truncated to 2147483647.
(node:15710) TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer.
Timer duration was truncated to 2147483647.
我想知道这是内存泄漏还是由我的代码引起的,还是其他原因。因为在错误信息中提到了32位,我想知道这是否与我使用的是2016年的64位Macbook Pro有关。 (节点 v10.17.0)
代码:
'use-strict'
const through = require('through2')
const http = require('http')
const port = process.argv[2]
const uppercaser = through(function (buffer, _, next) {
this.push(buffer.toString().toUpperCase())
next()
});
const server = http.createServer(function (req, res) {
if (req.method === 'POST') {
res.writeHead(200, { 'Content-Type': 'text/plain' })
req.pipe(uppercaser).pipe(res)
} else {
res.writeHead(404)
res.end()
}
});
server.listen(port)
Google 搜索给出了这个问题的各种原因 (example 1, example 2),似乎大多数解决方案都在使用的库中修复。
当我发现这种类型的错误是在我使用 setInterval
函数时。
这是因为超时的上限是2147483647,这是32位int的最大限制。
如果您愿意,可以制作自己的 setInterval
包装器
function setDaysTimeout(callback,days) {
// 86400 seconds in a day
let msInDay = 86400*1000;
let dayCount = 0;
let timer = setInterval(function() {
dayCount++; // a day has passed
if (dayCount === days) {
clearInterval(timer);
callback.apply(this, []);
}
}, msInDay);
}
并像这样使用它:
setDaysTimeout(function() {
console.log('Four days gone');
}, 4); // fire after 4 days
这是与 setTimeout
\ setInterval
函数相关的问题。如您所见,它们有 32 位的限制。因此 node
会警告您:
> setTimeout(console.log, +Infinity)
> (node:19903) TimeoutOverflowWarning: Infinity does not fit into a 32-bit signed integer.
Timeout duration was set to 1.
由于您的代码没有任何这些,因此库中的某些代码似乎有问题。
我建议 运行 node
使用 --trace-warnings
flag 来查找警告来源:
--trace-warnings
Print stack traces for process warnings (including deprecations).
超时上限为2147483647,这是32位int的最大限制。为了避免这种情况,您可以等待最长时间,然后等待任何剩余时间。
const timeout = async (callback, time, callbackArguments) => {
if (!callback || typeof callback !== 'function') throw new Error('Invalid Callback')
let args = ((callbackArguments && typeof callbackArguments === 'object' &&
callbackArguments.length > 0) ? callbackArguments : [])
let max = 2147483647
if (time > max) {
let t = Math.floor(time / max)
let r = time%max
for (let i = 0; i < t; i++) await (() => new Promise(res => setTimeout(() => res(), max)))();
if (r) {
return setTimeout(() => callback(...args), r)
} else {
return callback(...args)
}
} else {
return setTimeout(() => callback(...args), time)
}
}
这样使用
let a = 2
let b = 5
let c = (a, b) => console.log(!a && !b ? 0 : !a && b ? b : a && !b ? a : a + b)
let now = new Date().getTime()
let later = now + 2147483647*5
timeout(c, later-now, [a,b])
我正在学习课程 stream-adventure。其中一项任务是制作一个将所有请求转换为大写的 http 服务器,并在响应中 return 它。
现在我设法让它工作并且作业通过了。但是,控制台给了我一个 TimeoutOverflowWarning。
(node:15710) TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer.
Timer duration was truncated to 2147483647.
(node:15710) TimeoutOverflowWarning: 4294967296000 does not fit into a 32-bit signed integer.
Timer duration was truncated to 2147483647.
我想知道这是内存泄漏还是由我的代码引起的,还是其他原因。因为在错误信息中提到了32位,我想知道这是否与我使用的是2016年的64位Macbook Pro有关。 (节点 v10.17.0)
代码:
'use-strict'
const through = require('through2')
const http = require('http')
const port = process.argv[2]
const uppercaser = through(function (buffer, _, next) {
this.push(buffer.toString().toUpperCase())
next()
});
const server = http.createServer(function (req, res) {
if (req.method === 'POST') {
res.writeHead(200, { 'Content-Type': 'text/plain' })
req.pipe(uppercaser).pipe(res)
} else {
res.writeHead(404)
res.end()
}
});
server.listen(port)
Google 搜索给出了这个问题的各种原因 (example 1, example 2),似乎大多数解决方案都在使用的库中修复。
当我发现这种类型的错误是在我使用 setInterval
函数时。
这是因为超时的上限是2147483647,这是32位int的最大限制。
如果您愿意,可以制作自己的 setInterval
包装器
function setDaysTimeout(callback,days) {
// 86400 seconds in a day
let msInDay = 86400*1000;
let dayCount = 0;
let timer = setInterval(function() {
dayCount++; // a day has passed
if (dayCount === days) {
clearInterval(timer);
callback.apply(this, []);
}
}, msInDay);
}
并像这样使用它:
setDaysTimeout(function() {
console.log('Four days gone');
}, 4); // fire after 4 days
这是与 setTimeout
\ setInterval
函数相关的问题。如您所见,它们有 32 位的限制。因此 node
会警告您:
> setTimeout(console.log, +Infinity)
> (node:19903) TimeoutOverflowWarning: Infinity does not fit into a 32-bit signed integer.
Timeout duration was set to 1.
由于您的代码没有任何这些,因此库中的某些代码似乎有问题。
我建议 运行 node
使用 --trace-warnings
flag 来查找警告来源:
--trace-warnings
Print stack traces for process warnings (including deprecations).
超时上限为2147483647,这是32位int的最大限制。为了避免这种情况,您可以等待最长时间,然后等待任何剩余时间。
const timeout = async (callback, time, callbackArguments) => {
if (!callback || typeof callback !== 'function') throw new Error('Invalid Callback')
let args = ((callbackArguments && typeof callbackArguments === 'object' &&
callbackArguments.length > 0) ? callbackArguments : [])
let max = 2147483647
if (time > max) {
let t = Math.floor(time / max)
let r = time%max
for (let i = 0; i < t; i++) await (() => new Promise(res => setTimeout(() => res(), max)))();
if (r) {
return setTimeout(() => callback(...args), r)
} else {
return callback(...args)
}
} else {
return setTimeout(() => callback(...args), time)
}
}
这样使用
let a = 2
let b = 5
let c = (a, b) => console.log(!a && !b ? 0 : !a && b ? b : a && !b ? a : a + b)
let now = new Date().getTime()
let later = now + 2147483647*5
timeout(c, later-now, [a,b])