• Как запомнить текст, который выполняется в функции?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Основная проблема в получении body заключена в том, что request асинхронный. То есть ответ придет не сразу, а через какое то время, при этом, js не будет дожидаться этого ответа а продолжит выполнять код, находящийся после request-а. Это в свою очередь приведет к тому, что в этом коде мы не можем получить ответ request-а, так происходит потому, что ответ еще не пришел)
    Как же быть в этой ситуации???
    Почитать про ассинхронность, промисы и async/await

    Далее привожу простенький класс, умеющий кэшировать ответы requesta, и пример его использования:
    тык сюда

    var request = require("request");
    
    
    // создаем класс для кэширования результатов запросов
    class СacheRequest {
    	// конструктор
    	constructor(handler){
    		// создаем ассоциативный массив для кэширования результата
    		this.cache = {};
    	}
    	
    	// основной метод класса, предназначен для получения данных по ссылке
    	// принимает url в качестве параметра
    	// возвращает выполненный промис если запрос есть в кэше
    	// или промис в ожидании выполнения запроса
    	async get(url){
    		// если такой запрос уже был, возвращаем промис с результатом из кэша
    		if( this.cache[url] )
    			return  Promise.resolve(this.cache[url]);
    		
    		// иначе возвращаем промис с ожиданием результата
    		return new Promise((resolve,reject)=>{
    			// делаем запрос на указаный url
    			request(url, (error, response, body)=>{
    				// если ошибка - реджектим )
    				if( error )
    					return reject(error);
    				
    				// иначе запоминаем в кэше ответ
    				this.cache[url] = body;
    
    				// и резолвим body
    				resolve(body);
    			});			
    		});
    	}
    
    	// метод отчищает кэш
    	clear(){
    		this.cache = {};
    	}
    }
    
    // создаем экземпляр кэша
    const cacheRequest = new СacheRequest();
    
    // так как request асинхронный, то для того, чтобы получить 
    // результат запроса в "синхронном стиле" используем await
    
    // await можно использовать только внутри асинхронной функции.
    // для этой цели обернем блок с вызовами cacheRequest.get в
    // само вызывающуюся асинхронную функцию
    (async () => {
    	// выполняем запросы:
    	// запросим "http://google.ru/" (будет сделан фактический запрос)
    	let body = await cacheRequest.get("http://google.ru/");
    	console.log("\n\n\nBODY:", body, 111);
    
    	// еще раз запросим "http://google.ru/" (будет взято из кэша)
    	body = await cacheRequest.get("http://google.ru/");
    	console.log("\n\n\nBODY:", body, 222);
    })()
    
    // раз в сутки отчищаем кэш
    setTimeout(()=>{
    	cacheRequest.clear();
    }, 1000*60*60*24 ); // 1000*60*60*24 это количество миллисекунд в сутках

    Ответ написан
    1 комментарий