在先前调用的函数完成后,如何使用Promise调用函数?
例如,我想动态加载脚本并调用脚本中声明的函数。我没有保证就做到了,并发现了一个函数未找到错误。对如何使用Promise解决此类问题有帮助吗?
我的JS代码如下:
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 ) ;
}
其他选项是静态包含JS或在主JS中声明函数。但是,我想知道如何使用promises来完成,因为在JS编码时经常会遇到这种问题。
编辑:
尽管当前的问题已解决,但我仍然遇到相同的问题。让我们再来看一个例子。
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
} ) ;
一个人如何解决这样的问题?因为,从技术上讲,我应该等待上面的语句执行...
编辑#2:
任务是将事件处理程序添加到以特定ID开头的所有事件。在执行期间,将处理程序添加到所有事件,但是对于每个处理程序,仅显示最后一个元素的描述。我的理解告诉我这是由于JS的异步特性。请帮忙...
JS小提琴: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") ;
} ) ;
} ) ;
感谢大家的耐心和帮助...
答案 0 :(得分:2)
您可以像这样在addScript
函数中实现承诺:
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) ;
});
}
然后您可以像这样调用addScript
函数:
addScript('script.js').then(()=>{
console.log('script has loaded');
}).catch(e=>{
//handle error
});
答案 1 :(得分:1)
jQuery已经附带了$.getScript
函数:
jQuery(document).ready(async ($) => {
// setup option bar
await $.getScript ("../js/optionBar.js") ; // add script dynamically
setupOptionBar ("WatchDog") ; // function declared in optionBar.js
});
请注意,通常最好使用模块系统和捆绑程序(例如webpack)来管理模块,而不要依赖全局对象在您期望的位置。
这是一个可以在上述旧版浏览器上运行的版本:
jQuery(document).ready(function($) {
// setup option bar
$.getScript ("../js/optionBar.js", function() {
setupOptionBar ("WatchDog") ; // function declared in optionBar.js
});
});
答案 2 :(得分:0)
通过使用async
和await
,可以大大简化基于Promise的代码。 Babel可以将这些文件转译以供浏览器使用。
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);
});
}
注意ready
处理程序中的代码。在函数声明中添加一个async
关键字,然后在脚本加载时添加await
。
我们仍然需要对addScript
函数本身使用传统的promise,因为我们正在与旧式的回调代码集成,该代码需要直接访问resolve
和reject
的延续方法。