【发布时间】:2019-02-24 21:26:01
【问题描述】:
我注意到这里有些人建议在您想延迟执行某些事情时直接使用 await/async 和 promise 而不是 setTimeout。这是代码:
async wait (ms){
return new Promise(resolve => setTimeout(resolve, ms));
}
所以我会使用
await wait(3000);
my_function();
而不是
setTimeout(() => {
my_function();
}, 3000);
这是有道理的,但我注意到如果我这样做,我会增加内存使用量,并最终导致应用程序在几个小时后崩溃并出现大量内存。
这是 nodejs 的 Promise 设计中的问题,还是我在这里遗漏了什么?
这段代码重现了这个问题:
const heapdump = require('heapdump'),
fs = require('fs');
class test {
constructor(){
this.repeatFunc();
}
async wait (ms){
return new Promise(resolve => setTimeout(resolve, ms));
}
async repeatFunc(){
// do some work...
heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot');
await this.wait(5000);
await this.repeatFunc();
}
}
new test();
注意堆转储每 5 秒增加一次
使用 setInterval 不会发生这种情况:
const heapdump = require('heapdump'),
fs = require('fs');
class test {
constructor() {
setInterval(this.repeatFunc, 5000);
}
repeatFunc() {
// do some work...
heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot');
}
}
new test();
【问题讨论】:
-
请发布应用程序的完整代码(或至少一个重现内存泄漏的minimal reproducible example)。不,promise 不应该自行泄漏内存。你是如何调用等待的函数的?
-
我发布了重现问题的代码
-
您的代码很可能由于堆栈溢出而崩溃,来自
repeatFunc的无限递归。与async/await的承诺无关:-) -
也就是说,如果您使用尾递归 (
return this.repeatFunc()) 编写代码,那么 a good promise implementation should not leak memory -
如果我输入
return this.repeatFunc而不是await this.repeatFunc,它仍然会增加
标签: javascript node.js memory-leaks promise async-await