Challenges with asynchronous problems related to importing models utilizing promises in conjunction with the three.js

I'm currently struggling to resolve a promise in my script. The promise needs to be resolved when a function containing 3D file imports finishes importing, but I'm unsure how to make this happen.

Is there a way to receive a signal or data from the browser indicating that the model has finished loading so the promises can execute?

Below is the code snippet of the promise that should execute res() once generateContent() completes importing objects:

const myGeneralAsyncPromise = new Promise((res, rej) => {
    generateContent();
    if(some condition) res();
    // else rej();
});

myGeneralAsyncPromise.then(allIsReady, notReadyYet);

The following section invokes a class that creates various objects within generateContent():

var arrow3 = body(scene, world, 'static', 'arrow', { hx: 0.2, hy: 0.2, hz: 0.2 }, { x: 34.5, y: 3.35, z: 6 }, { x: 0, y: 11, z: 0 });
bodys.push(arrow3);

var phone = body(scene, world, 'static', 'phone', { hx: 1.3, hy: 1.3, hz: 1.3 }, { x: 35.35, y: 1.8, z: 6.5 }, { x: 0, y: 0, z: 0 });
bodys.push(phone);

var pencil = body(scene, world, 'static', 'pencil', { hx: 2, hy: 2, hz: 2 }, { x: 35.5, y: 1.8, z: 14 }, { x: 0, y: 11, z: 0 });
bodys.push(pencil);

The subsequent code block handles the actual import of each object:

function body(scene, world, bodyType, colliderType, dimension, translation, rotation) {
    new GLTFLoader_js_1.GLTFLoader().load(`src/models/${colliderType}.glb`, function (gltf) {
        var model = gltf.scene;
        collider = gltf.scene;
        model.scale.x = dimension.hx;
        model.scale.y = dimension.hy;
        model.scale.z = dimension.hz;
        
        // Additional processing for model here...

        scene.add(model);
    });
}

It's worth noting that generateContent() involves other time-consuming processes besides imports, with the import being the most time-consuming task.

To summarize, I need to implement a condition in my main promise that will trigger res() upon completion of the model loading process.

Answer №1

It is recommended to create a commitment that will be fulfilled once the load callback is triggered. Essentially, you should convert .load() into a promise:

const promiseGLTFLoad = url =>
    new Promise(resolve => new GLTFLoader_js_1.GLTFLoader().load(url, resolve));

Using this function allows you to construct asynchronous processing like so:

async function body(scene, world, bodyType, colliderType, dimension, translation, rotation) {
    const gltf = await promiseGLTFLoad(`src/models/${colliderType}.glb`);
    var model = gltf.scene;
    collider = gltf.scene
    model.scale.x = dimension.hx
    /* ... etc ... */
    scene.add(model);

    var gltfAnimations = gltf.animations;
    var mixer = new THREE.AnimationMixer(model);
    var animationsMap = new Map();
    gltfAnimations.filter(a => a.name != 'TPose')
                  .forEach(a => animationsMap.set(a.name, mixer.clipAction(a)));
    // It is essential to return the result!!
    return animationsMap;
}

Next, when you invoke the body function --- presumably in generateContent: ensure that the function gathers the promises and then awaits them:

async function generateContent() {
    // ...
    var arrow3Promise = body(scene, world, 'static', 'arrow', { hx: 0.2, hy: 0.2, hz: 0.2 }, {  x: 34.5, y: 3.35, z: 6 }, { x: 0, y:11, z: 0});
    var phonePromise = body(scene, world, 'static', 'phone', { hx: 1.3, hy: 1.3, hz: 1.3 }, {  x: 35.35, y:1.8, z: 6.5 }, { x: 0, y:0, z: 0});
    var pencilPromise = body(scene, world, 'static', 'pencil', { hx: 2, hy: 2, hz: 2 }, {  x: 35.5, y:1.8, z: 14 }, { x: 0, y:11, z: 0});

    // Await resolution of all promises
    var bodys = await Promise.all(arrow3Promise, phonePromise, pencilPromise);
    // ... etc
    return bodys; // Could be needed by the caller??
}

Lastly, the primary execution code would appear as follows:

async function main() {
    const bodys = await generateContent();
    if (something seems wrong) throw new Error("my error");
    // ...
    return bodys; // Might be required by the caller??
}

main().then(allIsReady, failure);

You may not necessarily require that many layers. Instead, you can verify if something is wrong at the end of generateContent and raise an error there (resulting in a rejected promise). In turn, it simplifies to:

generateContent().then(allIsReady, failure);

Note that there is no concept of "notReadyYet." A promise either resolves or rejects. If it rejects, it must be considered a failure. There is no room for the sentiment of "not yet" here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Delay the v-alert display after an item is added to the array basket using setTimeout

here is my custom rightTableMenu template <template> <div> <h1 align="center">{{ title }}</h1> <v-alert type="info" icon="mdi-emoticon-sad" v-if="basketStatus"> Empty Basket, please add some to basket < ...

Error encountered when utilizing a specialized jQuery extension: "not a function"

Every time I attempt to execute this function (function($) { $.fn.generateURLHash = function() { return document.URL.substr(document.URL.indexOf('#')+1); }; })(jQuery); when I call $.generateURLHash(), an error pops up in th ...

What is the best way to create a loop using JSON information?

Seeking assistance to create a loop using JSON data to display the title, link, and description of advertisements in HTML format. Provided is a JSON template with two ads, but my actual JSON contains 10-20 IDs. What am I overlooking in the code below? Sto ...

Adjusting the height of a textarea within a table

My textarea's height is supposed to be 500%, but it's not changing. I suspect that being inside a table might have something to do with the issue, but I'm unsure of what needs to be adjusted to set the height correctly. Surprisingly, the wid ...

AngularJS ng-map defines the view position using rectangular coordinates

Is there a way to set the position of ng-map view using the ng-map directive not as the center value of [40.74, -74.18], but instead as a rectangle defined by the corner values of the map view (north, south, east, west)? Currently, I have this code: < ...

Strategies for transmitting computed variables from a controller to JavaScript once the computation is complete?

Within my application, I have a button that triggers an action called "method" present in the UserController. This particular action involves executing some specific tasks. def method ***performing necessary calculations and operations*** @my_variable ...

Error in Javascript: Null Object

I have created an upload page with a PHP script for AJAX, but I'm encountering errors in Firebug. Also, the upload percentage is not being returned properly. Currently, I can only do one upload in Firefox and the script doesn't work in Chrome. H ...

Having trouble installing the 'ws' npm package on MacOS Big Sur?

Every time I try to install the websocket package using "npm install ws", I keep getting this error message: npm ERR! code ENOSELF npm ERR! Refusing to install package with name "ws" under a package npm ERR! also called "ws". Did you name your project the ...

405 status code returned for CORS request

Hello everyone, I need assistance with my CORS issue. I am trying to make an API request from another domain and encountering an error with the following code: var headers = { host: host, path: url + instance + '?action=reset', ...

Ways to verify whether a vue instance is empty within a .vue file by utilizing the v-if directive

I am facing an issue with a for-loop in Vue that iterates through a media object using v-for to check if it contains any images. Everything is working correctly, but I want to display a div below the loop saying "There is no media" when the object is empty ...

Internet Explorer IE 11 encounters an "Error: Object does not support property or method" issue

Recently, I started using the jquery circleChart.min.js plugin for creating a circle chart. It's been working perfectly on all browsers except for Internet Explorer 11 (IE11). I keep getting an error message when trying to run it in IE11. Can anyone h ...

What is the best way to save website information in SQL Server?

My website is www dot abc dot com and it contains some valuable content that I want to store in SQL Server. Can this be done using DOM? If not, please recommend alternative methods. I've searched this forum for similar solutions but haven't found ...

Is it possible for jQuery to analyze HTML contained within a variable?

Currently, I am utilizing PHP along with an ajax command to retrieve the complete HTML content from an external webpage using the file_get_contents() function in PHP. After storing this HTML in a JavaScript variable, I am curious if it is possible to uti ...

How can you assign a value to an HTML Input by dragging an SVG shape or canvas?

I am currently in the process of creating a user interface for setting pricing parameters. There are three categories that need to be visually represented, along with two sliders to determine suggested Buy/Sell prices. To demonstrate my progress so far, I ...

Difficulty encountered while connecting JSON data to a list using Angular JS

Currently, I am working on developing an application using AngularJS. In this project, I need to populate the customer list using data from a database. To achieve this, I have written a web method to retrieve the necessary data: [WebMethod] [ScriptMet ...

Why are XAxis categories appearing as undefined in tooltip when clicked?

[When clicking on the x-axis, the values go from 0 to 1. I need the x-axis categories values to display on click event. When hovering over the x-axis value, it shows properly, but clicking on the x-axis does not show the correct values] Check out this fid ...

The Angular Google Maps Module fails to initialize

After updating angular-google-maps to version 2.0.1 via bower and adding the required dependencies (bluebird, jquery, loadash), I noticed that my app works fine when I comment out google-maps. This suggests that the issue lies with angular-google-maps. He ...

Comparing JSON objects with JavaScript models: A guide

Currently I'm working with angular 2 and I have an array of data. data: MyModel[] = [ { id: 1, name: 'Name', secondName: 'SecondName' } In addition, I have created the interface MyModel: interface MyModel { id: number, nam ...

Alignment issue with Ul dropdown menus and shadow

After stumbling upon a fascinating menu design at this link, I decided to tweak it for center alignment by following the advice on this forum thread. Unfortunately, my efforts have hit a roadblock - the drop down menus aren't aligning as intended and ...

Trigger a function from a Bootstrap modal

Here is a preview of my HTML code : <form action="form2_action.php" method="post"> <table> <tr> <td>First Name </td> <td>:</td> <td><input type="text" id="f ...