简体   繁体   中英

Callback within a promise within a class?

I have a class that I use to load external resources via an XMLHttpRequest (this is for WebGL) so I'm loading models, shaders etc. My plan was to put a loading display up whilst it did all these requests and then when it's finally complete I want it to run a callback function from the original function that created it. However, I'm getting strange results when I try to run that call back (such as it has no access of any of the objects within the class that did the loading).

I can get around this problem by passing "this" into the loading class and then doing

self = this; 
promise(self.callback());

but I'd much rather specify the function that I want it to callback to after its done the loading. Does anyone know if this can be done? My code looks like this:

Main Class

this.loadingClass = new LoadingClass(this.LoadingComplete, resources);

Main.prototype.LoadingComplete = function()
{
    // Returns undefined if i specify the callback function instead of just "this"
    console.log(this.loadingClass.anyOfTheMembersOfThisClass);
}

Loading Class

LoadingClass = function(callback, resources) {

  ..

        Promise.all(resources).then(function(loadedResources)
        {
            ..
            callback();

        });
}

When you pass the function object as

(this.LoadingComplete, resources)

the object to which it was bound, will not be passed. So, only the function object LoadingComplete is passed to LoadingClass and when it is invoked as

callback()

the this value will be undefined (in strict mode).

To fix this,

  • you need to bind the this object, like this

     new LoadingClass(this.LoadingComplete.bind(this), resources) 
  • if your environment supports ES2015's Arrow functions

     new LoadingClass(() => this.LoadingComplete(), resources); 

In both these cases, when the LoadingComplete is invoked from LoadingClass , the this will be retained.

You are detouching callback (read about "this" ) function from the root object, so of course it loses context. Specify bindingContext explicitly with Function.prototype.bind method:

this.loadingClass = new LoadingClass(this.LoadingComplete.bind(this), resources);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM