How to deal with async loader?

If have a problem when I use a loader for one of my function.
Here’s the code I writed:

export function loadSTL(filepath, colorRGB) {
let inst;

// Load STL file
const loader = new STLLoader();
loader.load(
   filepath,
  (geometry) => { inst = STLToInstance(geometry, colorRGB); },
);

return inst;
}

The purpose of this is to return the var inst when the load is done.
Unfortunately, the function return null so I thought that the function return before the end of the load.

Does someone have an idea of what can I do for this?

What about this

export function loadSTL(filepath, colorRGB) {
    let inst

    // Load STL file
    const loader = new STLLoader()
    loader.load(
        filepath,
        (geometry) => { 
            inst = STLToInstance(geometry, colorRGB)
            return inst;
        },
    )
}

The function still return undefined. I don’t find a way to “wait” until the end of the load.

Couldn’t you use the new Loader.loadAsync() method? Checkout how this method is used in the following example:

https://threejs.org/examples/webgl_tonemapping

You should be able to use it with STLLoader, too.

3 Likes

Sounds like a similar problem that I had which was solved here:

Check the comment that was marked as solution

The only way to do exactly what you’d like to do is using async/await:

async function loadSomething() {
  return new Promise((resolve) => {
    const loader = new STLLoader();

    loader.load(
      filepath,
      (geometry) => resolve(STLToInstance(geometry, colorRGB)),
      () => resolve()
    });
  });
};

// Async / await require outer context to be an `async` function
(async function main() {
  const model = await loadSomething();

  console.log(model) // <- valid STL model instead of null / undefined

  scene.add(model);
})();

Non-async/await alternative that does exactly the same would be:

export function loadSTL(filepath, colorRGB) {
  return new Promise((resolve) => {
    const loader = new STLLoader();

    loader.load(
      filepath,
      (geometry) => resolve(STLToInstance(geometry, colorRGB)),
      () => resolve()
    });
  });
}

loadSTL.then((model) => {
  // Continue with model loaded
});

Loader.loadAsync() @Mugen87 mentioned above does the Promise approach.

Edit: Small fiddle with sample async/await https://jsfiddle.net/bur54veo/

2 Likes

I spent some time to find how to use this, maybe it will be useful for someone:

var gltfLoader = new THREE.GLTFLoader();
var result = await gltfLoader.loadAsync("car/scene.gltf");
...