Отпрaвка ответа клиенту с результатами работы функции [дубликат]

277
30 марта 2017, 21:31

На данный вопрос уже ответили:

  • Как вернуть значение из события или из функции обратного вызова? 2 ответа

Если request поместить в app.get, то всегда будет возвращаться пустая страница, а если поместить request перед app.get то значение будет отправлено клиенту.
Вопрос: как заставить app.get подождать пока request сделает свою работу и лишь тогда отправлять данные?

var express = require('express');
var cheerio = require('cheerio');
var request = require('request');
var app = express();
var text;
var headers = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'
};
var options = {
    url:'http://www.worldtimeserver.com/',
    headers:headers
};     
request(options,function(err,res,body) {
            $ = cheerio.load(body);
           text=( $('h1').text() );
});  
app.get('/', function (req, res) {
  res.send(text);
});
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
Answer 1

Немного магии:

var express = require('express'),
    cheerio = require('cheerio'),
    request = require('request'),
    events = require('events'); // Это встроенный модуль
var app = express();
var text;
text_state = new events.EventEmitter; // Нам понадобится событие "текст загружен"
var headers = {
    'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'
};
var options = {
    url:'http://www.worldtimeserver.com/',
    headers:headers
};
request(options,function(err,res,body) {
    $ = cheerio.load(body);
    text=$('h1').text();
    text_state.emit('ready'); // Вызываем событие загрузки
});
app.get('/', function (req, res) {
    if(text){ // если текст еще не загружен - то он undefined, так что мы идём и ждем события загрузки
        res.send(text);
    }else{
        text_state.on('ready',() => {
            res.send(text);
        });
    }
});
app.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});
Answer 2

А если засунуть request (вместе с options и headers) в обработчик app.get (перед res.send) разве он не будет именно так и делать?

P.S. Попробовал с промисом, конечно, чисто для интересу:
var express = require('express'), cheerio = require('cheerio'), request = require('request'); var app = express(); var text;

var headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36' };

var options = { url:'http://www.worldtimeserver.com/', headers:headers };

request(options,function(err,res,body) { $ = cheerio.load(body); text=$('h1').text(); }); app.get('/', function (req, res) {

new Promise(function(resolve) {
    resolve(text);
}).then(text => res.send(text));

});

app.listen(3000, function () { console.log('Example app listening on port 3000!'); });

Только лень въезжать, как блок скрипта вставить. Объяснил бы кто, что ли.

READ ALSO
Передача данных из java-сервиса в AngularJS (ng-table)

Передача данных из java-сервиса в AngularJS (ng-table)

Здравствуйте! У меня возникла следующая проблемаЕсть вполне рабочее веб-приложение на Java (Spring MVC), где, помимо прочего, делаются запросы в БД, а результаты...

271
Валидация в сафари

Валидация в сафари

Функция валидации полей ввода

364
Как авторизироваться на github c помощью node js?

Как авторизироваться на github c помощью node js?

Делаю скачку обновлений с github из своего репозитория(есть доступ) при помощи nodejs

333
Переключение анимации в горизонтальном меню

Переключение анимации в горизонтальном меню

Всем привет! Подскажите пожалуйста как можно реализовать подобное переключение меню, когда блок появляется только когда пункт меню активный?...

261