скачать изображение в асинхронной функции карты реагировать родной - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь выполнить асинхронную карту по списку объектов метаданных изображения.

Для каждого объекта в списке я проверяю, существует ли на устройстве строка device_path. Если это не так, я загружаю изображение на устройство, используя RNFetchBlob и параметр объекта download_url. После этого я обновляю объект device_path до вновь загруженного изображения.

При выполнении кода ниже, моя функция checkPaths возвращает {"_40":0,"_65":0,"_55":null,"_72":null}. Я хотел бы, чтобы функция возвращала это:

[
  { device_path: 'goodimagepath1', download_url: 'mysecretdownloadurl1' },
  { device_path: 'goodimagepath2', download_url: 'mysecretdownloadurl2' }
];

Как мне изменить мою функцию, чтобы она работала как положено?

import React, { Component } from "react";
import { View, Text } from "react-native";
import RNFetchBlob from "rn-fetch-blob";

async function checkPaths(image_metadata_list) {

  const promises = image_metadata_list.map(async (image_metadata, idx) => {

    RNFetchBlob.fs.exists(image_metadata.device_path).then(exists => {
      if (exists === false) {
        console.log("image does not exist on device, downloading...");
        const dirs = RNFetchBlob.fs.dirs;
        const filename = (idx + 1).toString() + '.jpg'
        RNFetchBlob.config({
          path: dirs.DocumentDir + `/user_images/${filename}`
        }).fetch('GET', `${image_metadata.download_url}`).progress((received = 0, total = 0) => {
          //Handle progress of download here.. May be update UI...\
        }).then((resp) => {
          // update the device path
          image_metadata.device_path = resp.path();
          console.log("image path modified", image_metadata);
          return image_metadata;
        }).catch(e => {
          console.log("error downloading image", e);
        })
      }
      else {
        console.log("image path OK", image_metadata)
        return image_metadata;
      }
    })
  })
  console.log("promises", promises)
  results = await Promise.all(promises)
  return results;
}


export default class App extends Component {
  constructor(props) {
    super(props);
    this.image_references = [
       { device_path: 'badimagepath1', download_url:'mysecretdownloadurl1' },
       { device_path: 'badimagepath2', download_url: 'mysecretdownloadurl2' }
    ];
  }
  componentDidMount() {
    console.log("component mounted");
    console.log("checking image paths", JSON.stringify(this.image_references));
    checked_paths = checkPaths(this.image_references);
    console.log("checked image paths", JSON.stringify(checked_paths));
  }
  render() {
    return (
      <View style={{ flex: 1 }}>
        <Text>Welcome to MWE</Text>
      </View>
    )
  }
}

1 Ответ

0 голосов
/ 16 января 2019

Поскольку checkPaths асинхронный, он возвращает обещание. Это должно быть обработано в componentDidMount примерно так:

checkPaths(this.image_references).then(checked_paths => {
      console.log("resolved promise", checked_paths)
      console.log("checked image paths", JSON.stringify(checked_paths));
    }).catch(e => {
      console.log("error checking image paths", e)
    });

Я также изменил функцию checkPaths, чтобы дождаться проверки пути к изображению и дождаться загрузки изображения.

Если есть более чистый способ сделать это, я весь слух.

import React, { Component } from "react";
import { View, Text } from "react-native";
import RNFetchBlob from "rn-fetch-blob";

async function checkPaths(image_metadata_list) {

  const promises = image_metadata_list.map(async (image_metadata, idx) => {

    const exists = await RNFetchBlob.fs.exists(image_metadata.device_path)

    if (exists === false) {
      console.log("image does not exist on device, downloading...");
      const dirs = RNFetchBlob.fs.dirs;
      const filename = (idx + 1).toString() + '.jpg'

      const resp = await RNFetchBlob.config({
        path: dirs.DocumentDir + `/user_images/${filename}`
      }).fetch('GET', `${image_metadata.download_url}`).progress((received = 0, total = 0) => {
        //Handle progress of download here.. May be update UI...\
      }).then((resp) => {
        // update the device path
        image_metadata.device_path = resp.path();
        console.log("image path modified", image_metadata);
      }).catch(e => {
        console.log("error downloading image", e);
      })
    }
    else {
      console.log("image path OK", image_metadata);
    }
    return image_metadata;
  })
  return await Promise.all(promises);
}


export default class App extends Component {
  constructor(props) {
    super(props);
    this.image_references = [
      { device_path: 'badimagepath1', download_url: 'https://firebasestorage.googleapis.com/v0/b/fivedates-dev.appspot.com/o/user_images%2FoHK9DQ94ZZOBIejbVO8luJZnEU22%2F1.jpg?alt=media&token=6c5e053d-45b4-4ab0-a52b-65c1180624ed' },
      { device_path: 'badimagepath2', download_url: 'https://firebasestorage.googleapis.com/v0/b/fivedates-dev.appspot.com/o/user_images%2FoHK9DQ94ZZOBIejbVO8luJZnEU22%2F1.jpg?alt=media&token=6c5e053d-45b4-4ab0-a52b-65c1180624ed' }
    ];
  }
  componentDidMount() {
    console.log("component mounted");
    console.log("checking image paths", JSON.stringify(this.image_references));

    checkPaths(this.image_references).then(checked_paths => {
      console.log("resolved promise", checked_paths)
      console.log("checked image paths", JSON.stringify(checked_paths));
    }).catch(e => {
      console.log("error checking image paths", e)
    });
  }
  render() {
    return (
      <View style={{ flex: 1 }}>
        <Text>Welcome to MWE</Text>
      </View>
    )
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...