Мы проверим, что на самом деле происходит, когда вы объявляете
var
иlet
один за другим.Case1: используя
var
Теперь откройте окно консоли Chrome, нажав F12 и обновите страницу. Расходуйте каждые 3 функции внутри массива. Вы увидите свойство, называемое
[[Scopes]]
. Разместите это. Вы увидите один объект массива с именем"Global"
, разверните его. Вы найдете свойство'i'
, объявленное в объект, имеющий значение 3.Вывод:
- Когда вы объявляете переменную с помощью
'var'
вне функции, она становится глобальной переменной (вы можете проверить, введяi
илиwindow.i
в окне консоли. return 3).- Объявленная вами анонимная функция не вызовет и не проверит значение внутри функции, если вы не вызываете функции.
- Когда вы вызываете функцию,
console.log("My value: " + i)
принимает значение из его объектаGlobal
и отобразить результат.CASE2: использование let
Теперь замените
'var'
на'let'
]
Сделайте то же самое, перейдите в области. Теперь вы увидите два объекта
"Block"
и"Global"
. Теперь разворачиваем объектBlock
, вы увидите там 'i', и странно, что для каждой функции значение ifi
отличается (0, 1, 2).Заключение:
Когда вы объявляете переменную, используя
'let'
даже вне функции, но внутри цикла, эта переменная будет не будет глобальной переменной, она станет переменной уровняBlock
, которая доступна только для одной и той же функции. Именно поэтому мы получаем значениеi
для каждой функции при вызове функций.Для получения более подробной информации о том, как работает ближе, пройдите через удивительный видеоурок https://youtu.be/71AtaJpJHw0
public class CountMaxFlatFileItemReader extends FlatFileItemReader {
private int counter;
private int maxCount;
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
@Override
public Object read() throws Exception {
counter++;
if (counter >= maxCount) {
return null; // this will stop reading
}
return super.read();
}
}
Что-то вроде этого должно работать. Читатель перестает читать, как только возвращается null.
Лучшим соглашением является запись делегата, который отвечает за отслеживание количества прочитанных записей и прекращение после фиксированного счета; компоненты должны позаботиться о контексте выполнения, чтобы обеспечить перезапуск
class CountMaxReader<T> implements ItemReader<T>,ItemStream
{
private int count = 0;
private int max = 0;
private ItemReader<T> delegate;
T read() {
T next = null;
if(count < max) {
next = delegate.read();
++count;
}
return next;
}
void open(ExecutionContext executionContext) {
((ItemStream)delegate).open(executionContext);
count = executionContext.getInt('count', 0);
}
void close() {
((ItemStream)delegate).close(executionContext);
}
void update(ExecutionContext executionContext) {
((ItemStream)delegate).update(executionContext);
executionContext.putInt('count', count);
}
}
Это работает с любым читателем.
Для FlatFileItemReader
, а также любого другого ItemReader
, который продолжается AbstractItemCountingItemStreamItemReader
, существует свойство maxItemCount
. Путем настройки этого свойства ItemReader
будет продолжать считываться до тех пор, пока не будет выполнено одно из следующих условий:
maxItemCount
. В любом из двух указанных выше условий нуль будет возвращен читателем, указывая на Spring Batch, что вход завершен.
Если у вас есть какие-либо пользовательские реализации ItemReader
, которые должны удовлетворять этому требованию, я бы рекомендовал расширить AbstractItemCountingItemStreamItemReader
и перейти оттуда.