我有一个离子应用程序需要下载数据(带分页)并以递归方式将其插入数据库(如管道)。我正在使用(Angular' s)$ 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上运行我的测试。
我在递归函数中使用大数据,所以我的问题与其他递归内存泄漏问题有点不同。
感谢。
答案 0 :(得分:3)
你的代码工作方式太难了,承诺链,所以当你做一点延期舞蹈时 - 你真的可以链接应该解决泄漏的承诺作为更好的代码的副作用:
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);
}
这就是整个代码,它说: