Can I run a JS script from another using `fetch`?

23,152

Solution 1

Fetch API is supposed to provide promise-based API to fetch remote data. Loading random remote script is not AJAX - even if jQuery.ajax is capable of that. It won't be handled by Fetch API.

Script can be appended dynamically and wrapped with a promise:

const scriptPromise = new Promise((resolve, reject) => {
  const script = document.createElement('script');
  document.body.appendChild(script);
  script.onload = resolve;
  script.onerror = reject;
  script.async = true;
  script.src = 'foo.js';
});

scriptPromise.then(() => { ... });

SystemJS is supposed to provide promise-based API for script loading and can be used as well:

System.config({
  meta: {
    '*': { format: 'global' }
  }
});

System.import('foo.js').then(() => { ... });

Solution 2

There are a few things to mention on here.


Yes, it is possible to execute a javascript just loaded from the server. You can fetch the file as text and user eval(...) while this is not recommended because of untrackeable side effects and lack of security!

Another option would be: 1. Load the javascript file 2. Create a script tag with the file contents (or url, since the browser caches the file)

This works, but it may not free you from callback hell perse.


If what you want is load other javascript files dinamically you can use, for example requirejs, you can define modules and load them dinamically. Take a look at http://requirejs.org/


If you really want to get out of the callback hell, what you need to do is

  • Define functions (you can have them in the same file or load from another file using requirejs in the client, or webpack if you can afford a compilation before deployment)
  • Use promises or streams if needed (see Rxjs https://github.com/Reactive-Extensions/RxJS)
  • Remember that promise.then returns a promise

    someAsyncThing()
      .then(doSomethingAndResolveAnotherAsncThing)
      .then(doSomethingAsyncAgain)
    

Remember that promises can be composed

Promise.all(somePromise, anotherPromise, fetchFromServer)
  .then(doSomethingWhenAllOfThoseAreResolved)
Share:
23,152
mike rodent
Author by

mike rodent

Updated on July 05, 2022

Comments

  • mike rodent
    mike rodent almost 2 years

    Lower intermediate JS/JQ person here.

    I'm trying to escape callback hell by using JS fetch. This is billed as "the replacement for AJAX" and seems to be pretty powerful. I can see how you can get HTML and JSON objects with it... but is it capable of running another JS script from the one you're in? Maybe there's another new function in ES6 to do:

    $.getScript( 'xxx.js' );
    

    i.e.

    $.ajax({ url : 'xxx.js', dataType : "script", });
    

    ...?

    later, response to Joseph The Dreamer:

    Tried this:

    const createdScript = $(document.createElement('script')).attr('src', 'generic.js');
    fetch( createdScript )...
    

    ... it didn't run the script "generic.js". Did you mean something else?