简体   繁体   English

递归创建诺言时如何避免内存泄漏?

[英]How to avoid memory leak when creating promises recursively?

I have an ionic application which needs to download data (with pagination) and insert it into database recursively (like a pipeline). 我有一个离子应用程序,需要下载数据(分页)并将其递归插入数据库(如管道)。 I'm creating promises with (Angular's) $q service. 我正在用(Angular)的$ q服务创建承诺。 The problem is that when I call this recursive function, the data is being downloaded and inserted successfully, however memory usage is always increasing, and when the promise chain resolves completely, allocated memory still remains in use. 问题是,当我调用此递归函数时,正在成功下载并插入数据,但是内存使用率一直在增加,并且当promise链完全解析后,分配的内存仍然保持使用状态。

Here is my recursive function: 这是我的递归函数:

// offset:  last downloaded row count
// limit:   row count to download at each page
// numRows: row count to download at all
function dowloadAndInsert(offset, limit, numRows) {
    var deferred = $q.defer();

    // Recursion step: We do not reached at the end of data
    if((offset + limit) <= numRows) {

        // Download the data
        downloadData(offset, limit)
            .then(function(response) {

                // Insert the data
                insertData(response)
                    .then(function(insertTime) {

                        // Recursion step
                        dowloadAndInsert(offset + limit, limit, numRows)
                            .then(function() {
                                deferred.resolve();
                            })
                            .catch(function(reason) {
                                deferred.reject(reason);
                            });
                    })
                    .catch(function(reason) {
                        deferred.reject(reason);
                    });
            })
            .catch(function(reason) {
                deferred.reject(reason);
            });
    }

    // Base case: We reached at the end of data
    else {
        var remainingRows = numRows % limit;        // Means the last limit actually

        // If exists, insert remaining rows
        if(remainingRows !== 0) {

            // Download the last piece of data
            downloadData(offset, remainingRows)
                .then(function(response) {

                    // Insert the last piece of data
                    insertData(response)
                        .then(function(insertTime) {

                            // Base case, successfully downloaded and inserted everything
                            deferred.resolve();
                        })
                        .catch(function(reason) {
                            deferred.reject(reason);
                        });
                })
                .catch(function(reason) {
                    deferred.reject(reason);
                });
        }

        else {
            // Base case, successfully downloaded and inserted everything
            deferred.resolve();
        }
    }

    return deferred.promise;
}

Note: response object coming from downloadData function is a big data, it sometimes contains 100.000 rows with 18 columns. 注意:来自downloadData函数的响应对象是一个大数据,有时包含100.000行和18列。 Total memory usage is becoming like 1GB. 总的内存使用量正在变成1GB。 I'm running my tests on iPad Air 2. 我正在iPad Air 2上运行测试。

I'm playing with big data in my recursion function, so that my question is a bit different from other recursive memory leak questions. 我在递归函数中使用大数据,因此我的问题与其他递归内存泄漏问题有所不同。

Thanks. 谢谢。

Your code is working way too hard, promises chain, so when you do the little deferred dance - you could really just chain promises which should resolve the leak as a side effect of the better code: 您的代码工作方式太辛苦,承诺链,所以当你的小舞延期-你能真的只是链,其应解决泄漏为更好的代码的副作用承诺:

function dowloadAndInsert(offset, limit, numRows) {
  const start = offset,
        numFetch = ((offset + limit) <= numRows ? limit : numRows % limit;
  if(numFetch === 0) {
     return Promise.resolve(); // we're done;
  }
  return downloadData(start, end).
           then(insertData).
           then(downloadAndInsert.bind(null, offset + numFetch, limit, numRows);
}

And that's the entire code, it says: 这就是整个代码,它说:

  • Check how many rows I need to fetch and insert. 检查我需要提取并插入多少行。
  • If I don't need to fetch anymore rows - just return an empty promise. 如果我不再需要获取行,则只需返回一个空的Promise。
  • Otherwise fetch as many as we need - and then fetch the remaining rows. 否则,获取所需数量的内容-然后获取剩余的行。

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

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