仅在javascript

时间:2018-08-29 17:04:28

标签: javascript asynchronous promise

在先前调用的函数完成后,如何使用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") ;
    } ) ;
} ) ;

感谢大家的耐心和帮助...

3 个答案:

答案 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)

通过使用asyncawait,可以大大简化基于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,因为我们正在与旧式的回调代码集成,该代码需要直接访问resolvereject的延续方法。