Как я могу реализовать несколько обещаний внутри цикла - PullRequest
0 голосов
/ 08 мая 2019

я пытаюсь отфильтровать изображения по названию или описанию, используя запрос getinfo мерцания, который возвращает эту информацию.

я пытаюсь отправить запрос getinfo для каждого изображения в массиве изображений в настоящее время, посмотреть, соответствуют ли заголовок или описание вводу пользователя и, если да, отобразить этот новый массив отфильтрованных изображений.

Я не могу решить, как сделать вызов для каждого изображения, и только после того, как цикл завершен и отфильтрованный массив завершен, вызовите setState для этого массива.


  filterImages = (filter) =>{
    if(filter.length === 0)
      return;

    const currentImages = this.state.images;
    console.log(currentImages[0]);
    const newFilterdImages =[];
    const baseUrl = 'https://api.flickr.com/';

    for (const img of currentImages){
      axios({
      url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
      baseURL: baseUrl,
      method: 'GET'
    })
    .then(res=> res.data)
    .then(res=> {
      if( res && res.photo) {
        const imageInfo = res.photo;
        //console.log(imageInfo.title._content,imageInfo.description._content);

        if(imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter)){
            newFilterdImages.push(img);
        }
      }
    }).then( res => console.log("first then " + newFilterdImages)) // output the newFilterdImages array on each call
    }

    this.setState({images:newFilterdImages}) // this will not work 
  }

как я могу дождаться окончания цикла и только затем изменить текущий массив новыми изображениями фильтра?

Ответы [ 2 ]

1 голос
/ 08 мая 2019

В Javascript Обещание представляет некоторый будущий результат, возможно, медленной операции.Реализация результата Обещания включает в себя запуск .then() на нем.

Чтобы упростить ожидание множества будущих результатов, для вас предусмотрен метод Promise.all().Он берет список Обещаний и возвращает Обещание, которое разрешается с будущими значениями всех предоставленных Обещаний.

Комбинируя эти точки, мы можем запустить axios на всех изображениях, сопоставляя список изображенийк списку Обещаний:

let axioses = currentImages.map((img) => {
  return axios({
      url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
      baseURL: baseUrl,
      method: 'GET'
  })
})

... и затем запускаем Promise.all() в результирующем списке и рассматриваем его как обещание, которое разрешается со списком результатов из axios(), когда они всев наличии:

Promise.all(axioses).then((results) => {
      const filteredResults = results.filter((res) => {
         if (!res || !res.photo) {
            return false
         }

         const imageInfo = res.photo;

         return imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter))
     )

     this.setState({ images: filteredResults.map(res => res.photo) })
})
1 голос
/ 08 мая 2019

Вам нужно использовать Promise.all(), чтобы дождаться разрешения всех изображений перед их фильтрацией и присвоением состоянию

filterImages = (filter) =>{
    if(filter.length === 0)
      return;

    const currentImages = this.state.images;
    console.log(currentImages[0]);
    const newFilterdImages =[];
    const baseUrl = 'https://api.flickr.com/';
    const promises = [];
    for (const img of currentImages){
      promises.push(axios({
      url: `services/rest/?method=flickr.photos.getinfo&api_key=22c1f9009ca3609bcbaf08545f067ad&photo_id=${img.id}&&format=json&safe_search=1&nojsoncallback=1`,
      baseURL: baseUrl,
      method: 'GET'
    })
    .then(res=> res.data)
    }
    Promise.all(promises).then((data) => {
        data.forEach((item, index) => {
             if( item && item.photo) {
                 const imageInfo = res.photo;
                 if(imageInfo.title._content.includes(filter) || imageInfo.description._content.includes(filter)){
                       newFilterdImages.push(currentImages[index]);
                 }
             }
        });
        this.setState({images:newFilterdImages})
    })
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...