1

How do I use promises to call a function after a previously called function has been finished?

For example, I want to load a script dynamically and call a function declared within the script. I did that without promises and got a function not found error. Any help with how to use promises to solve this kind of problem?

My JS code is as below:

jQuery ( document ). ready ( function ()
{
    // setup option bar
    addScript ("../js/optionBar.js") ; // add script dynamically
    setupOptionBar ("WatchDog") ; // function declared in optionBar.js
} ) ;
function addScript ( url )
{
    var script = document. createElement ("script") ;
    script. src = url ;

    document. head. appendChild ( script ) ;
}

Other options would be to include JS statically or declare function in main JS. But, I want to know how this can be done with promises as this kind of problem is faced regularly while coding in JS.

Edit:

Despite the current problem being solved, I still got the same question. Let's look at it with another example.

jQuery ( document ). ready ( function ()
{
    jQuery ( div ). css ( { "height" : "200px" } ) ; // modifying heights of 30 divs
    jQuery ("#div30"). html ( jQuery ("#div30"). css ("height") ) ; // should put 200 in #div30 but 100 appears as modification is still in progress
} ) ;

How would one tackle such a problem? Because, I am technically supposed to wait for the above statement to execute...

Edit#2:

The task is to add event handler to all events starting with certain ID. During execution, handler is added to all events but for every handler only the description of last element is shown. My understanding tells me its because of JS's asynchronous nature. Please, help...

JS Fiddle: http://jsfiddle.net/xpvt214o/707184/

jQuery ("[id^='WTM_appOptionTitle_']"). each ( function ()
{
    module = jQuery ( this ). attr ("id"). replace ("WTM_appOptionTitle_" , "") ; // store name of module
    jQuery ("#WTM_appOptionTitle_" + module ). hover (
    function ()
    {
        jQuery ("#WTM_appOptionDescription_" + module ). addClass ("wtm_appoptiondescriptionshow") ; // module has the value of last module only when this statement is executed
    } ,
    function ()
    {
        jQuery ("#WTM_appOptionDescription_" + module ). removeClass ("wtm_appoptiondescriptionshow") ;
    } ) ;
} ) ;

Thanks everyone for your patience and help...

13
  • I don't see any attempt to use Promises in your code... what's the issue? Commented Aug 29, 2018 at 17:06
  • you dont need a promise there. just wait for the onLoad event of the script tag.For sure you could wrap this in a promise if you want Commented Aug 29, 2018 at 17:08
  • the function setupOptionBar is not found and gives error. I wanna know how to solve this problem witht the use of promises or without it's use. @tehhowch Commented Aug 29, 2018 at 17:16
  • that's what I need help with, how to wrap this thing into a promise?? @mr.void Commented Aug 29, 2018 at 17:17
  • @SamagraSinghTomar He's right. First try without promises, use a regular callback approach and learn how to wait for a script to have been loaded/executed. Commented Aug 29, 2018 at 19:09

3 Answers 3

3

You could implement a promise in your addScript function like this:

function addScript(url){
    return new Promise((resolve, reject) => {
        var script = document.createElement("script");
        script.src = url ;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script) ;
    });

}

Then you could call the addScript function like this:

addScript('script.js').then(()=>{
    console.log('script has loaded');
}).catch(e=>{
    //handle error
});
Sign up to request clarification or add additional context in comments.

2 Comments

Simplify toscript.onload = resolve. Also don't forget to set up an appropriate error handler.
@Bergi Good call
1

jQuery already ships with a $.getScript function:

jQuery(document).ready(async ($) => {
    // setup option bar
    await $.getScript ("../js/optionBar.js") ; // add script dynamically
    setupOptionBar ("WatchDog") ; // function declared in optionBar.js
});

Note it is generally better to use a module system and a bundler (like webpack) for managing modules rather than relying on global objects being where you'd expect them to be.

Here is a version that works on really old browsers of the above:

jQuery(document).ready(function($) {
    // setup option bar
    $.getScript ("../js/optionBar.js", function() {
      setupOptionBar ("WatchDog") ; // function declared in optionBar.js
    });
});

Comments

1

You can vastly simplify your promises based code by using async and await. Babel can transpile these to be used in the browser.

jQuery(document).ready(
  async () => {                                 // notice `async` here
    await addScript ("../js/optionBar.js");     // notice `await` here
    setupOptionBar ("WatchDog");
  });

function addScript(url)
{
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.src = url ;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild (script);
  });
}

Notice the code in the ready handler. Add an async keyword to the function declaration and then await on the script loading.

We do still need to use a traditional promise for the addScript function itself because we're integrating with old-style callback code which requires direct access to the resolve and reject continuation methods.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.