【问题标题】:How to use Promises correctly with multiple requests如何正确使用 Promises 处理多个请求
【发布时间】:2018-06-27 07:54:27
【问题描述】:

我正在使用 twitter 的 API 通过查询特定的哈希标签来接收最近的推文。第一个 GET 请求是到search/tweets,它在它的参数中接受主题标签和其他查询。对此的响应返回一组推文(对象)。我将这些 id 中的每一个都推送到一个外部数组中。现在我想遍历这个数组并为每个 ID 再次调用statuses/show,以便我可以获得发布推文的用户的位置数据。 statuses/show 端点只需要一个推文 ID,但我有一个数组。我将如何对一组 ID 使用相同的 getRequest 函数?

我尝试通过在线阅读 Promises 来实现它,但它不起作用。

这是我的代码:

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;
});

【问题讨论】:

    标签: node.js api twitter ecmascript-6 es6-promise


    【解决方案1】:

    你几乎猜对了!将所有推文映射到您的 getRequest() 函数返回的 Promises。然后,Promise.all() 方法将返回一个 Promise,当你的数组中的所有 Promise 都解决时,它就会解决。 顺便说一句,您可以使用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

    【讨论】:

    • 我收到一个错误,ret.push 不是函数。在阅读了有关 reduce 的更多信息后,我做了以下更改 -> gyazo.com/885226def49e85742636373551d104e8 但我仍然收到这些错误 -> gyazo.com/c4754ebb822ad4e20e47c2fdba3d513c
    • reduce 大致相当于:let ret = []; arr.forEach( item => if(//something) ret.push(item) )。我猜你现在可以试试这样。
    • reduce 函数回调中返回的任何内容都被推送到 accumulator 变量。在我之前的评论中,第一个链接包含我编写的代码。你能告诉我line 57 是否会将一系列承诺返回到ret 并因此返回到requests 或只是ret
    • 我想我在line 60 上遇到了这个错误,因为requests 未定义
    • @ShashankKaul 我为您创建了一个 jsfiddle,希望您能解决您的问题;)查看here
    【解决方案2】:

    换行

    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) );
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 2019-04-04
    • 2020-10-26
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    相关资源
    最近更新 更多