Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.11.2017, 03:17
Новичок на форуме
Отправить личное сообщение для Rora_ Посмотреть профиль Найти все сообщения от Rora_
 
Регистрация: 05.11.2017
Сообщений: 2

Непредсказуемая функция.
Всем добрый день. В процессе прочтения книги М.Каскиаро "Шаблоны проектирования Node.JS", описана следующая проблема, техническая сторона возникновения которой от меня ускользает, я опишу проблему тут, так как она описана в книге, прошу растолковать и так сказать помочь в понимании.

Есть функция результат выполнения которой не предсказуем:

const fs = require('fs');
const cache = {};
function inconsistentRead(filename, callback) {
	if (cache[filename]){
		callback(cache[filename]);
	}else{
		fs.readFile(filename,'utf-8',(err,data)=>{
			cache[filename]=data;
			callback(data);
		});
	}
}

function createFileReader(filename) {
	const listeners = [];
	inconsistentRead(filename,value=>{
		listeners.forEach(listener=>listener(value)); 
	});
	return {
		onDataReady: listener=>listeners.push(listener) // во 1 я первый раз увидел присвоение свойства таким элегантным образом, если можно, ссылку где об этом можно почитать. А во 2 что есть listener в данном случае?
	};
}

const reader1 = createFileReader('text.txt');
reader1.onDataReady(data=>{
	console.log('First call data:'+data);
	const reader2 = createFileReader('text.txt');
	reader2.onDataReady(data=>{
		console.log('Second call data:'+data)
	})
});

Выведет
First call data: Some data

И в 3 самое главное, автор пишет:
ВО время создания reder1 функция inconsistentRead() выполняется асинхронно, поскольку в кэше еще нет результата. Таким образом имеется возможность зарегистрировать обработчика, что и будет сделано в другой итерации цикла событий, до завершения операции чтения.
Затем в итерации цикла событий создастся reader2, когда файл уже находится в кэше. В этом случае внутренний вызов, inconsistentRead() ,будет выполнен синхронно. То есть он выполнит функцию обратного вызова немедленно, и соответственно все обработчики события reader2 также будут вызваны синхронно. Однако регистрация обработчиков выполняется после создания reader2, поэтому они никогда не будут вызваны.

Вот, этот итог меня ввел в ступор. Растолкуйте плз, о каких обработчиках идет речь. И почему вообще это так работает. Спасибо.
Ответить с цитированием
  #2 (permalink)  
Старый 05.11.2017, 14:43
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

Речь, как я понимаю, про inconsistentRead.

Если есть функция с колбеком, и этот колбек в некоторых случаях может вызваться только асинхронно (в данном примере - при отсутствии данных в кэше), то функция должна быть написана так, чтобы колбек всегда вызывался асинхронно.

Для наличия данных в кэше добавляем асинхронность искусственно:
if (cache[filename]){
    process.nextTick(callback, cache[filename]);
}
Ответить с цитированием
  #3 (permalink)  
Старый 05.11.2017, 15:27
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

А вообще, данный пример правильнее через промисы делать. Тогда и заморочки с listeners не понадобятся, и асинхронность промис берет на себя.
Ответить с цитированием
  #4 (permalink)  
Старый 07.11.2017, 08:34
Новичок на форуме
Отправить личное сообщение для Rora_ Посмотреть профиль Найти все сообщения от Rora_
 
Регистрация: 05.11.2017
Сообщений: 2

Да, спасибо я понял. Действительно, с промисами намного легче.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функция вызывается несколько раз KiberQ Общие вопросы Javascript 11 01.03.2017 15:45
js рекурсивная функция с for.. in циклом frying Общие вопросы Javascript 6 25.08.2014 10:50
не вызывается функция при изменении option soft4you Общие вопросы Javascript 1 23.07.2014 17:41
AJAX функция для новых html-элементов broadcast77 AJAX и COMET 25 03.03.2014 14:01
функция и несуществующий id Ankh Элементы интерфейса 4 10.02.2012 23:49