繁体   English   中英

在第n个setTimeout中解析的promise是否会导致内存泄漏?

[英]Does promise resolved in n-th setTimeout cause memory leak?

我可以在Chrome任务管理器中看到,正在运行以下代码的标签占用了越来越多的内存,并且直到解决承诺后才会释放该标签

UPDATE

这里的主要思想是使用单个“低级”方法来处理服务器的“忙”响应。 其他方法只是将带有请求数据的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))
    })

第一次在此调用_call()

async function getBalance () {
    return new Promise((resolve, reject) => {
        _call('/balance', null, resolve)
    })
}

它不会调用resolve回调,它将返回被拒绝的new Promise() ,因此您在getBalance()拥有的new Promise()最初将什么都不做。 请记住,由于_call被标记为async ,当您抛出该_call时,它会被捕获并变成被拒绝的承诺。

当计时器触发时,它将调用resolve()并解决getBalance()承诺,但它没有值,因此您无法获得余额。 到您最终调用resolve(response.balance) ,您已经调用了resolve()函数,因此它所属的promise已被锁定,并且不会更改其值。


就像其他人所说的那样,此代码有很多错误(很多反模式)。 这是我在node.js或答案中的代码段中运行时的简化版本:

 function delay(t, val) { return new Promise(resolve => { setTimeout(resolve.bind(null, val), t); }); } var counter = 1; function post() { console.log(`counter = ${counter}`); // modified counter value to 100 for demo purposes here return (counter++ < 100) ? { busy: true } : { balance: 3000 }; } function getBalance () { async function _call() { let response = post(); if (response.busy) { // delay, then chain next call await delay(10); return _call(); } else { return response.balance; } } // start the whole process return _call(); } getBalance() .then(balance => console.log('balance: ', balance)) .catch(e => console.error('some err: ', e)) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM