簡體   English   中英

遞歸創建諾言時如何避免內存泄漏?

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

我有一個離子應用程序,需要下載數據(分頁)並將其遞歸插入數據庫(如管道)。 我正在用(Angular)的$ q服務創建承諾。 問題是,當我調用此遞歸函數時,正在成功下載並插入數據,但是內存使用率一直在增加,並且當promise鏈完全解析后,分配的內存仍然保持使用狀態。

這是我的遞歸函數:

// 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;
}

注意:來自downloadData函數的響應對象是一個大數據,有時包含100.000行和18列。 總的內存使用量正在變成1GB。 我正在iPad Air 2上運行測試。

我在遞歸函數中使用大數據,因此我的問題與其他遞歸內存泄漏問題有所不同。

謝謝。

您的代碼工作方式太辛苦,承諾鏈,所以當你的小舞延期-你能真的只是鏈,其應解決泄漏為更好的代碼的副作用承諾:

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);
}

這就是整個代碼,它說:

  • 檢查我需要提取並插入多少行。
  • 如果我不再需要獲取行,則只需返回一個空的Promise。
  • 否則,獲取所需數量的內容-然后獲取剩余的行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM