【发布时间】:2018-07-25 14:20:35
【问题描述】:
我可以在 Chrome 任务管理器中看到,运行以下代码的选项卡占用了越来越多的内存,并且直到 promise 解决后才会释放
更新
这里的主要思想是使用单一的“低级”方法来处理来自服务器的“忙碌”响应。其他方法只是将带有请求数据的 url 路径传递给它并等待有价值的响应。
删除了一些反模式。
var counter = 1
// emulates post requests sent with ... axios
async function post (path, data) {
let response = (counter++ < 1000) ? { busy: true } : { balance: 3000 }
return Promise.resolve(response)
}
async function _call (path, data, resolve) {
let response = await post()
if (response.busy) {
setTimeout(() => {
_call(path, data, resolve)
}, 10)
throw new Error('busy')
}
resolve(response.balance)
}
async function makePayment (amount) {
return new Promise((resolve, reject) => {
_call('/payment/create', {amount}, resolve)
})
}
async function getBalance () {
return new Promise((resolve, reject) => {
_call('/balance', null, resolve)
})
}
makePayment(500)
.then(() => {
getBalance()
.then(balance => console.log('balance: ', balance))
.catch(e => console.error('some err: ', e))
})
【问题讨论】:
-
Don't use
return await,避免Promiseconstructor antipattern,不要传递resolve,在最小级别承诺(setTimeout),不要抛出永远不会被捕获的错误! -
不确定内存,但该代码几乎包含所有的承诺反模式:p
-
这段代码应该积累“未处理的承诺拒绝”错误,但它不应该泄漏任何自身的内存。
-
在 10 毫秒的计时器上一遍又一遍地调用自己可能不会给垃圾收集器足够的时间来完成其正常工作。这可能是您看到内存不断增加直到整个过程完成的部分原因。
-
仅供参考,这是您的代码的清理版本,它删除了 Promise 反模式:jsfiddle.net/jfriend00/9349nuLs
标签: javascript memory-leaks es6-promise