2016-04-25 2 views
11

Я новичок в Node.js, поэтому я все еще обволакиваю асинхронные функции и обратные вызовы. Моя борьба теперь заключается в том, как вернуть ответ после чтения данных из файла в асинхронной операции.Node.js и Express: как вернуть ответ после асинхронной операции

Я понимаю, что отправка ответа как это работает (и это работает для меня):

app.get('/search', function (req, res) { 
    res.send("request received"); 
}); 

Однако, теперь я хочу, чтобы прочитать файл, выполнить некоторые операции над данными, а затем возвращают приводит к ответу. Если операции, которые я хотел выполнить для данных, были простыми, я мог бы сделать что-то вроде этого - выполнить их встроенный и поддерживать доступ к объекту res, потому что он все еще находится в пределах области видимости.

app.get('/search', function (req, res) { 
    fs.readFile("data.txt", function(err, data) { 
     result = process(data.toString()); 
     res.send(result); 
    }); 
}); 

Однако файловые операции мне нужно выполнить длинные и достаточно сложны, что я разделил их в свою собственную функцию в отдельном файле. В результате, мой код выглядит примерно так:

app.get('/search', function (req, res) { 
    searcher.do_search(res.query); 
    // ??? Now what ??? 
}); 

Мне нужно позвонить res.send для того, чтобы отправить результат. Однако я не могу назвать это непосредственно в функции выше, потому что do_search завершает асинхронно. И я не могу назвать это в обратном вызове do_search, потому что объект res там не находится.

Может кто-нибудь помочь мне понять, как правильно обращаться с этим в Node.js?

+0

Я бы сказал, либо передать 'res' объект в качестве параметра в функцию, или сделать так, вы можете передать функцию в качестве параметра, а затем вызвать его, когда работа будет завершена (т.е. создать свой собственный Перезвони). Последнее, вероятно, было бы лучше, поскольку оно не связывает ваш код с API Express. –

ответ

13

Для доступа к переменной в другой функции, когда нет общей области действия, передайте ее в качестве аргумента.

Вы можете просто пройти res, а затем получить доступ как к query, так и к send по одной переменной внутри функции.


В целях разделения опасностей, возможно, вам лучше отказаться от обратного вызова.

Тогда do_search нужно знать только о выполнении запроса, а затем запустить функцию. Это делает его более общим (и, следовательно, многоразовым).

searcher.do_search(res.query, function (data) { 
    res.send(...); 
}); 

function do_search(query, callback) { 
    callback(...); 
} 
+1

Передача обратного вызова, безусловно, путь. +1 за предложение. –

+0

Спасибо за помощь. Я в конечном итоге изменил функцию do_search, чтобы принять обратный вызов, и он отлично работает. – ekl

+0

Ответит ли это на вопрос? Почему в этом примере нет 'app.get', который является рассматриваемой функцией? – nobar