У меня есть ионное приложение, которое должно загружать данные (с разбивкой на страницы) и вставлять их в базу данных рекурсивно (например, конвейер). Я создаю обещания с услугой ($). Проблема в том, что когда я вызываю эту рекурсивную функцию, данные загружаются и вставляются успешно, однако использование памяти всегда увеличивается, и когда цепочка обещаний полностью разрешается, выделенная память все еще используется.
Вот моя рекурсивная функция:
// 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;
}
Примечание. Объект ответа, поступающий из функции loadData, представляет собой большую информацию, иногда содержит 100 000 строк с 18 столбцами. Общее использование памяти составляет 1 ГБ. Я запускаю свои тесты на 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);
}
И что весь код, он говорит: