node.js: подождите, пока все потоки не будут выполнены

Я пишу скрипт hubot в coffeescript. Сценарий открывает три потока, каждый из которых выполняет запрос YQL. Если каждый поток отправляет свое сообщение в чат-клиент (в моем случае Slack), клиент умирает. Теперь мне нужно каким-то образом собрать строки из всех потоков и объединить их в одну команду отправки, как мне лучше это сделать?

slack_message = '*Todays menu*'
for i in [1..3]
  query = "select * from html where url='XPATH.. ["+i+"] XPATH.."
  new YQL.exec query, (response) ->
    m = response.query.results;
    slack_message += m

msg.send slack_message

person hansaplast    schedule 15.07.2015    source источник


Ответы (1)


Вы всегда можете вести счетчик:

slack_message = '*Todays menu*'
queries_done = 0

for i in [1..3]
  query = "select * from html where url='XPATH.. ["+i+"] XPATH.."
  new YQL.exec query, (response) ->
    m = response.query.results
    slack_message += m

    if queries_done is 3
      msg.send slack_message

Вы также можете использовать обещания:

Promise = require("promise")

call_query = (query) ->
  new Promise (resolve) ->
    new YQL.exec query, (response) ->
      resolve response.query.results;

get_menu = ->
  slack_message = '*Todays menu*'
  queries = []
  for i in [1..3]
    queries.push (call_query "select * from html where url='XPATH.. ["+i+"] XPATH..")

  Promise.all(queries).then (messages) ->
    msg.send slack_message + messages.join()

Промисы — это альтернатива обратным вызовам для асинхронной логики, и вы можете делать с ними отличные вещи, такие как Promise.all, это как раз то, что вы ищете. Он принимает массив из Promise объектов, и когда все они разрешены, он продолжает выполнять .then. Если у вас есть вечер, я предлагаю прочитать немного о них. Они могут сделать вещи лучше, как только вы поймете, как они работают.

person Kevin Chavez    schedule 16.07.2015
comment
спасибо, обещания были именно тем, что я искал, в итоге я использовал это. Можете ли вы изменить свой ответ и добавить Promise = require("promise") в начало и заменить promises.push на queries.push? Этого мне не хватало, чтобы заставить его работать - person hansaplast; 16.07.2015
comment
ой! отредактировал имя переменной, но, видимо, я пропустил один га. Рад, что вы нашли их полезными! - person Kevin Chavez; 16.07.2015