Нижеприведенный сценарий позволяет иметь один обработчик для всех условий выхода. Он использует специальную функцию обратного вызова для выполнения пользовательского кода очистки.
cleanup.js
// Object to capture process exits and call app specific cleanup function
function noOp() {};
exports.Cleanup = function Cleanup(callback) {
// attach user callback to the process event emitter
// if no callback, it will still exit gracefully on Ctrl-C
callback = callback || noOp;
process.on('cleanup',callback);
// do app specific cleaning before exiting
process.on('exit', function () {
process.emit('cleanup');
});
// catch ctrl+c event and exit normally
process.on('SIGINT', function () {
console.log('Ctrl-C...');
process.exit(2);
});
//catch uncaught exceptions, trace, then exit normally
process.on('uncaughtException', function(e) {
console.log('Uncaught Exception...');
console.log(e.stack);
process.exit(99);
});
};
Этот код перехватывает неперехваченные исключения, Ctrl-C и обычные события выхода. Затем он вызывает одну необязательную функцию обратного вызова очистки пользователя перед ее выходом, обрабатывая все условия выхода с помощью одного объекта.
Модуль просто расширяет объект процесса, а не определяет другой эмитент событий. Без специального обратного вызова приложения очистка по умолчанию не имеет функции op. Этого было достаточно для моего использования, когда дочерние процессы оставались включенными при выходе из Ctrl-C.
Вы можете легко добавить другие события выхода, такие как SIGHUP, по желанию. Примечание: в руководстве NodeJS SIGKILL не может иметь слушателя. В приведенном ниже тестовом коде показаны различные способы использования cleanup.js
// test cleanup.js on version 0.10.21
// loads module and registers app specific cleanup callback...
var cleanup = require('./cleanup').Cleanup(myCleanup);
//var cleanup = require('./cleanup').Cleanup(); // will call noOp
// defines app specific callback...
function myCleanup() {
console.log('App specific cleanup code...');
};
// All of the following code is only needed for test demo
// Prevents the program from closing instantly
process.stdin.resume();
// Emits an uncaught exception when called because module does not exist
function error() {
console.log('error');
var x = require('');
};
// Try each of the following one at a time:
// Uncomment the next line to test exiting on an uncaught exception
//setTimeout(error,2000);
// Uncomment the next line to test exiting normally
//setTimeout(function(){process.exit(3)}, 2000);
// Type Ctrl-C to test forced exit
Вы не можете сделать это без итерации. Если вы хотите избежать традиционного цикла, вы все равно можете использовать forEach
:
brandList.forEach(brand -> brand.setSelected(false));
Вам, очевидно, нужно будет перебрать список. Не существует механизма установки памяти, который бы позволял такие тонкости, особенно учитывая, что объекты не хранятся рядом друг с другом.
Но если вы просто не хотите писать это сами, используйте forEach ():
brandList.forEach(tag -> tag.setSelected(false));
Есть способ сделать то, что вы хотите, без итерации по каждому объекту.
ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ : это грязный, смешной и довольно сложный способ. Если реализовано, вы должны получить доступ к своему значению selected
только через isSelected()
(что является общим требованием инкапсуляции).
Вы должны действительно повторить это, но я даю вам «решение» ради эксперимента.
Теперь, когда я сначала поставил отказ от ответственности:
Создать объект «Переключатель», который вы можете дать всем им, класс должно выглядеть следующим образом:
class Switch {
private boolean switchedOff = false;
private LocalDateTime lastSwitchOff;
public boolean isSwitchedOff() {
return switchedOff;
}
public void switchOff() {
switchedOff = true;
lastSwitchOff = LocalDateTime.now();
}
public LocalDateTime getLastSwitchOff() {
return lastSwitchOff;
}
}
Как только ваш переключатель переключен, все вызовы isSelected()
вашего объекта Tag
вернут false, если вы не установите их снова. Вот как вы добавляете его в свой Tag
класс:
public class Tag {
private final String title;
private final String id;
private boolean selected;
private Switch theSwitch;
private LocalDateTime lastModified;
public boolean isSelected() {
if (theSwitch != null && theSwitch.isSwitchedOff() && lastModified.isBefore(theSwitch.getLastSwitchOff())) return false;
else return selected;
}
public void setSelected(boolean selected) {
lastModified = LocalDateTime.now();
this.selected = selected;
}
public Tag(String id, String title, boolean selected, Switch theSwitch) {
lastModified = LocalDateTime.now();
this.id = id;
this.title = title;
this.selected = selected;
this.theSwitch = theSwitch;
}
...
}
И затем вы можете использовать его следующим образом:
public static void main(String[] args) {
Switch mySwitch = new Switch();
List<Tag> brandList = new ArrayList<>();
brandList.add(new Tag("1", "A", false, mySwitch));
brandList.add(new Tag("2", "v", true, mySwitch));
brandList.add(new Tag("3", "f", false, mySwitch));
brandList.add(new Tag("4", "g", true, mySwitch));
brandList.add(new Tag("5", "y", true, mySwitch));
brandList.add(new Tag("18", "y", true, mySwitch));
brandList.add(new Tag("16", "j", true, mySwitch));
brandList.add(new Tag("19", "m", false, mySwitch));
mySwitch.switchOff();
// Now all of the isSelected() calls will return false
}