-1

I'm fairly new to both F# and Fable. I have the following code in JavaScript to load up some images and then do stuff with them when they're all loaded:

async function start() {
  async function loadImages(files) {
    let promises = files.map(filename => {
      return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = filename;
        img.onload = () => resolve(img);
      })
    });
    return Promise.all(promises);
  }

  const images = await loadImages(imageFileNames);
  // Do stuff with images
  console.log('images loaded', images);
}
start();

How would I go about writing this in F# for use in Fable?

I'm using the Fable Simple Template (which I believe is Fable 1.x not the new version 2?)

Alf Nathan
  • 19
  • 5

1 Answers1

1

This is what I've come up with, which does the job although I'm sure there's a nicer way:

let loadImages imageFileNames callback =
    let mutable remaining : int = (imageFileNames |> List.length) - 1

    let imagesWithNames =
        imageFileNames
        |> List.map (fun fileName ->
            let img = Browser.document.createElement_img()
            fileName,img
        )

    let images =
        imagesWithNames
        |> List.map (fun (_,img) -> img)

    for (fileName, img) in imagesWithNames do
        img.onload <- (fun _ ->
            if remaining > 0 then
                remaining <- remaining - 1
            else
                callback(images)
            ())
        img.src <- fileName
    ()

// Use with a callback, e.g.
let imageFileNames = [ "grass.png" ; "hedge.png" ];
loadImages imageFileNames (fun images -> printfn "%A" images)

This was inspired/copied from this javascript version: https://stackoverflow.com/a/41170913

Alf Nathan
  • 19
  • 5