问题描述
我注意到这里有些人建议您使用await/async并在希望延迟执行某些操作时直接使用promise而不是setTimeout.这是代码:
I noticed some people here recommend to use await/async and promise instead of setTimeout directly when you want to delay the execution of something. This is the code:
async wait (ms){
return new Promise(resolve => setTimeout(resolve, ms));
}
所以我会用
await wait(3000);
my_function();
代替
setTimeout(() => {
my_function();
}, 3000);
这是有道理的,但我注意到,如果这样做,则会增加内存使用率,并最终在几个小时后由于内存不足而使应用程序崩溃.
It makes sense but I noticed that if I do that I get increased memory usage and eventually the app crashes with heap of out memory after a few hours.
这是nodejs的promise设计中的问题,还是我在这里遗漏了什么?
Is this an issue in the promise design of nodejs, or am I missing something here?
此代码重现了该问题:
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秒不断增加
Notice heap dump keeps increasing every 5 seconds
使用setInterval不会发生这种情况:
With setInterval this doesn't happen:
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();
推荐答案
您已经编写了一个无限递归函数,每个函数调用都返回一个新的Promise.每个诺言都在等待从内部诺言中解决-是的,它当然是在累积内存.如果代码是同步的,那么您将获得堆栈溢出异常.
You have written an infinitely recursive function, and each function call returns a new promise. Each promise is waiting to be resolved from the inner one - so yes, it of course is accumulating memory. If the code was synchronous, you would have gotten a stack overflow exception instead.
只需使用循环即可:
const heapdump = require('heapdump'),
fs = require('fs');
async function wait(ms){
return new Promise(resolve => setTimeout(resolve, ms));
}
async function repeat() {
while (true) {
// do some work...
heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot');
await wait(5000);
}
}
repeat().then(() => console.log("all done"), console.error);
包括我在内,因为promise易于使用,尤其是当您要从异步任务返回结果值或处理错误时.但是,如果您对promise的优点不满意,那么没有什么可以迫使您将已经工作的代码转换为promise.只需继续使用回调样式,直到找到对Promise有用的地方即可.
Well that includes me, as promises are much easier to work with, especially when you want to return a result value from your asynchronous task or handle errors. But if you're not convinced by any of the advantages of promises, there is nothing that forces you convert your already-working code to promises. Just carry on using callback style until you find a good use for promises.
这篇关于Node.js承诺设计中发生内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!