【问题标题】:How can I pass original data with the response for a Promise.map using bluebird?如何使用 bluebird 将原始数据与 Promise.map 的响应一起传递?
【发布时间】:2015-05-23 01:02:39
【问题描述】:

我有一个名为 photos 的数组,它在 Promise 中返回:

  somePromiseFunc.then (resp) ->
    photos = _.filter resp, 'invalid'
    photos
  .map (photo) ->
    request
      url: photo.url
      method: 'GET'
  .each (photo_contents) ->
    # HERE I NEED THE ORIGINAL photo and the photo_contents

如何在响应中将photophoto_contents 放在一起?这样的事情可能吗?

【问题讨论】:

    标签: javascript coffeescript promise bluebird


    【解决方案1】:

    你可以使用Promise.all:

    somePromiseFunc.then (resp) ->
      photos = _.filter resp, 'invalid'
      photos
    .map (photo) ->
      Promise.all [
        photo
        request
          url: photo.url
          method: 'GET'
      ]
    .each ([photo, contents]) ->
    

    由于您使用的是 bluebird,如果您更喜欢在对象而不是数组中传递值,您也可以使用 Promise.props,但在这种特殊情况下真正要做的只是增加一些额外的冗长:

    somePromiseFunc.then (resp) ->
      photos = _.filter resp, 'invalid'
      photos
    .map (photo) ->
      Promise.props 
        photo: photo
        contents: request
          url: photo.url
          method: 'GET'
    .each ({photo, contents}) ->
    

    【讨论】:

    • 您也可以使用{photo, contents: … } 来减少冗长,但我想知道括号(和额外的行!)或重复是否更冗长:-)
    • @Bergi 第二种方法比第一种方法多使用 13 个非空白字符。 Coffeescript 用户讨厌 非空白字符。 ;-) 不过,说真的,仅仅为了拥有它们而添加属性名称对我来说感觉很笨拙,尤其是当有很好的数组解构语法可用时。如果 OP 将 map 的结果传递到某个地方而不是立即传递到 each,我会说第二种方法有优点。
    【解决方案2】:

    最简单的方法是将它们组合到您的 map 回调中:

    somePromiseFunc().then (resp) ->
      _.filter resp, 'invalid'
    .map (photo) ->
      request
        url: photo.url
        method: 'GET'
      .then (photo_content) ->
        [photo, photo_content]
    .each ([photo, content]) ->
      # …
    

    当然你也可以使用一个对象而不是一个数组作为元组。


    另一种方法是 access the previous promise result somehow 然后 zip 将数组放在一起:

    photos = somePromiseFunc().then (resp) ->
      _.filter resp, 'invalid'
    contents = photos.map (photo) ->
      request
        url: photo.url
        method: 'GET'
    Promise.all [photos, contents]
    .then ([photos, contents]) ->
      Promise.each (_.zip photos, contents), ([photo, content]) ->
        # …
    

    【讨论】:

    • 这种嵌套的 Promise 似乎……不太理想
    • @Shamoon:你并没有真正嵌套 Promise,而是将它们嵌套在一个循环中。有关使用 Promise.all 而不是内部 .then 的非常相似的方法,请参阅 JLRishe 的回答(+1 给他)
    猜你喜欢
    • 2012-10-16
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2019-10-25
    相关资源
    最近更新 更多