Используйте обещания для вызова функции только после завершения другого в JavaScript - PullRequest
0 голосов
/ 29 августа 2018

Как использовать обещания для вызова функции после завершения ранее вызванной функции?

Например, я хочу динамически загрузить скрипт и вызвать функцию, объявленную в скрипте. Я сделал это без обещаний и получил функцию not found error. Любая помощь с тем, как использовать обещания для решения такого рода проблемы?

Мой код 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. Но я хочу знать, как это можно сделать с помощью обещаний, так как с такими проблемами регулярно сталкиваются при кодировании в JS.

Edit:

Несмотря на то, что текущая проблема решается, у меня все тот же вопрос. Давайте посмотрим на это другим примером.

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
} ) ;

Как можно решить такую ​​проблему? Потому что технически я должен ждать выполнения вышеуказанного оператора ...

Edit # 2:

Задача - добавить обработчик событий ко всем событиям, начинающимся с определенного идентификатора. Во время выполнения обработчик добавляется ко всем событиям, но для каждого обработчика отображается только описание последнего элемента. Мое понимание подсказывает мне это из-за асинхронного характера JS. Пожалуйста, помогите ...

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") ;
    } ) ;
} ) ;

Спасибо всем за терпение и помощь ...

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

jQuery уже поставляется с функцией $.getScript:

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

Обратите внимание, что обычно лучше использовать систему модулей и пакет (например, веб-пакет) для управления модулями, а не полагаться на глобальные объекты, находящиеся там, где вы ожидаете их увидеть.

Вот версия, которая работает на действительно старых браузерах:

jQuery(document).ready(function($) {
    // setup option bar
    $.getScript ("../js/optionBar.js", function() {
      setupOptionBar ("WatchDog") ; // function declared in optionBar.js
    });
});
0 голосов
/ 30 августа 2018

Вы можете значительно упростить код, основанный на обещаниях, используя async и await. Вавилон может использовать их в браузере.

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, потому что мы интегрируемся с кодом обратного вызова старого стиля, который требует прямого доступа к методам продолжения resolve и reject.

0 голосов
/ 29 августа 2018

Вы можете реализовать обещание в вашей функции 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
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...