RuntimeErrorz
RuntimeErrorz

Reputation: 47

Three.js asynchronous loading issue

I was trying to find the maximium value of a pointcloud data as following code.

import { PLYLoader } from "three/examples/jsm/loaders/PLYLoader";

let max_x = -Infinity;

function initModel() {
  new PLYLoader().load("../data/division/1.ply", (geometry) => {
    for (let j = 0; j < geometry.attributes.position.count; j += 3)
      max_x = Math.max(max_x, geometry.attributes.position.array[j]);
  });
}

function print() {
  console.log(max_x);
}

initModel();
print();//got -Infinity

But it didn't work because Three.js loaded the file asynchronously. I tried a few ways to solve this problem. I tried to add async and await before them like this.

import { PLYLoader } from "three/examples/jsm/loaders/PLYLoader";

let max_x = -Infinity;

async function initModel() {
  new PLYLoader().load("../data/division/1.ply", (geometry) => {
    for (let j = 0; j < geometry.attributes.position.count; j += 3)
      max_x = Math.max(max_x, geometry.attributes.position.array[j]);
  });
}

async function print() {
  await initModel();
  console.log(max_x);
}

print();//still got -Infinity

But I still got -Infinity, I have searched the web, but examples don't seem to do something in the callback function of load as I did. But setTimeout() worked. Any help would be appericated.

Upvotes: 1

Views: 472

Answers (1)

Berthur
Berthur

Reputation: 4495

As you discovered, the file is being loaded asynchronously. Your second code still doesn't work because even if initModel() is now asynchronous, it does not await load(), it just calls it and returns. Since PLYLoader.load() is not defines as an async function, you also can't just await it.

I recommend to familiarize with asynchronous javascript programming in general. The easiest thing to do is just to let your logic be asynchronous too, and print() inside the callback, like so:

function initModel() {
    new PLYLoader().load("../data/division/1.ply", (geometry) => {
        for (let j = 0; j < geometry.attributes.position.count; j += 3)
            max_x = Math.max(max_x, geometry.attributes.position.array[j]);

        print();
    });
}

If you absolutely want some synchronous code, you can always await a promise that checks with regular time intervals whether your model has finished building. But more likely, you are going to want to do run something else meanwhile rather than to block your program waiting for this to happen. There are usually ways of adapting your program logic to asynchronous logic, and it's almost certainly better.

Upvotes: 1

Related Questions