2017-02-01 6 views
0

Мне нужна помощь с ES6 Посылы цепочки в обработке массивов.Как связывать обещание в массиве

Как обрабатывать/определять каждый элемент массива, который переходит в метод Promise.all, когда есть другой метод асинхронного решения внутри?

Вот упрощенный пример:

function getData(data, callback) { 
    let groupPromises = data.map(row => { 
     var coordinates = getCoordinates(row); 
     return Promise.resolve({ 
      "place": getPlaces(coordinates), //how to invoke this method 
      "data": row 
     }; 
    });  
    Promise.all(groupPromises) 
     .then(groups => callback(groups)) 
     .catch(err => console.log(err)); 
    } 
} 

function getPlaces(coordinates) { 
    return new Promise(function(resolve, reject) { 
     if(coordinates == null) { 
      reject(); 
     } 
     parameters = { 
      location: [coordinates.latitude, coordinates.longitude], 
      rankby: "distance", 
     }; 
     googlePlaces.searchPlace(parameters, function (error, response) { 
      if (error) { 
       reject(error); 
      }; 
      resolve(response); 
     }); 
    } 
} 

ответ

1

Вы можете сделать это, как это, где вы добавляете .then() обработчик первого обещании, который получает place и тогда, когда это доступно возвращает объект, который вы хотите. Разрешенные результаты вашего Promise.all() тогда будет массив объектов, которые вы хотите:

function getData(data, callback) { 
    let groupPromises = data.map(row => { 
     var coordinates = getCoordinates(row); 
     // add .then() handler here to convert the place result 
     // into the object you want it in 
     return getPlaces(coordinates).then(place => { 
      return {place: place, data: row}; 
     }); 
    });  
    return Promise.all(groupPromises) 
     .then(groups => callback(groups)) 
     .catch(err => { 
      console.log(err); 
      throw err; 
     }); 
    } 
} 

function getPlaces(coordinates) { 
    return new Promise(function(resolve, reject) { 
     if(coordinates == null) { 
      reject(); 
     } 
     parameters = { 
      location: [coordinates.latitude, coordinates.longitude], 
      rankby: "distance", 
     }; 
     googlePlaces.searchPlace(parameters, function (error, response) { 
      if (error) { 
       reject(error); 
      }; 
      resolve(response); 
     }); 
    } 
} 

FYI, так как вы конвертируете к обещаниям, почему бы не просто вернуть обещание от getData() и не использовать функцию обратного вызова там вообще ? Ваш текущий код не имеет возможности сообщить об ошибке от getData(), что является чем-то, что поставляется в основном бесплатно с обещаниями.

На самом деле с чистыми обещаниями, getData() может быть упрощена следующим образом:

function getData(data, callback) { 
    return Promise.all(data.map(row => { 
     return getPlaces(getCoordinates(row)).then(function(place) { 
      return {place: place, data: row}; 
     }); 
    }));  
}