如何使用 bluebird 将原始数据与 Promise.map 的响应一起传递?

How can I pass original data with the response for a Promise.map using bluebird?

我有一些名为 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?这样的事情可能吗?

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

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

当然你也可以使用对象而不是元组的数组。


另一种方法是 and then 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.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}) ->