Как правильно использовать Обещания с несколькими запросами - PullRequest
0 голосов
/ 27 июня 2018

Я использую Twitter API для получения последних твитов, запрашивая определенные хэш-теги. Первый запрос GET - search/tweets, который принимает хэштег и другие запросы в своих параметрах. Ответ для этого возвращает массив твитов (объектов). Я помещаю каждый из этих идентификаторов во внешний массив. Теперь я хочу пройтись по этому массиву и сделать еще один вызов statuses/show для каждого из этих идентификаторов, чтобы я мог получить данные о местоположении пользователя, отправляющего твит. Конечная точка statuses/show принимает только один идентификатор твита, но у меня есть массив. Как мне использовать ту же функцию getRequest для массива идентификаторов?

Я пытался реализовать это, читая онлайн об Обещаниях, но это не работает.

Вот мой код:

function getRequest(url, params) {
    return new Promise(function (success, failure) {
        twitterSearch.get(url, params, function (error, body, response) {
            if (!error) {
                success(body);
            } else {
                failure(error);
            }
        });
    });
}

app.post('/twitter', (req, res) => {
  console.log("body", req.body);
  var tweetIDs = [];
  var bounds = [];
  getRequest('search/tweets', {q: req.body.tag, result_type:'recent', count:'100'})
  .then((tweets) => {
    tweets.statuses.map((status) => {
      if(status.user.geo_enabled) {
        console.log("ID: ", status.id);
        tweetIDs.push(status.id);
      }
    });
    return getRequest('statuses/show', tweetIDs); //I know tweetIDs is wrong, dont know what to do from here.
  }).then((data) => {
    console.log("User data for the ID")
    console.log(data);
  }).catch((error) => {
    console.log(error)
  });
  res.send(bounds);
  bounds.length = 0;
});

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Заменить строку

return getRequest('statuses/show', tweetIDs); //I know tweetIDs is wrong, dont know what to do from here.

с

return Promisel.all( tweetIDs.map( (tId) => getRequest('statuses/show', tId) );
0 голосов
/ 27 июня 2018

Вы почти правильно поняли! Сопоставьте все твиты с обещаниями, возвращенными вашей функцией getRequest(). Затем метод Promise.all() вернет вам одно обещание, которое разрешается, когда разрешаются все обещания в вашем массиве. Кстати, вы можете использовать Array.reduce вместо map, чтобы одновременно фильтровать и отображать ваш массив, это немного улучшит ваш код.

getRequest('search/tweets', {q: req.body.tag, result_type:'recent', count:'100'})

  .then( tweets => {
    let requests = tweets.statuses.reduce( (ret,status) => {
      if(status.user.geo_enabled)
          // The following is still wrong though, I guess. Format the params of getRequest accordingly.
          ret.push( getRequest('statuses/show', status.id) );
      return ret;
    }, []);
    return Promise.all(requests);
  })

  .then( results => {
     results.forEach( res => {
        console.log("User data for the ID");
        console.log(res);
     })
  })

РЕДАКТИРОВАТЬ: Связанные jsfiddle

...