Как вызвать вспомогательную функцию в функции Promise'd - PullRequest
0 голосов
/ 06 февраля 2019

Я все еще новичок в Javascript, и я надеюсь, что кто-то может помочь мне с проблемой, которая у меня возникла, потому что я просто не смог обернуть голову !!

У меня естьфункция с большим количеством дублирующегося кода, поэтому попытался выделить ее во вспомогательную функцию.Однако когда я вызываю вспомогательную функцию изнутри функции lMS (которая в настоящее время вызывается как lMS(f).then(), вспомогательная функция выполняет ПОСЛЕ функции init(g), которая зависит от выполнения и завершения lMS в первую очередь.

Я на 99% уверен, что у меня возникла эта проблема из-за моего неправильного понимания работы Promise и характера асинхронных функций.

Я пытался поместить дублирующий код в отдельную функцию и вызывать его, когда это необходимо.Я попытался захватить ответы этого как Обещания, или поместить ответы в массив, а затем выполнить только тогда, когда мне возвращены все элементы (по сравнению с исходным массивом).

Ниже приведен оригинал скрипт, где нет вспомогательной функции, но есть хороший кусок дублирующего кода: https://github.com/willstocks-tech/dynamically-polyfill-features-for-a-script/releases/tag/0.0.5b5 - строка 57 (function loadMyScript(url))

Я поместил вспомогательный код в Codepen (Iработаю над этим в течение нескольких дней) https://codepen.io/willstocks_tech/pen/pGgRrG?editors=1012

Обновление

Включена init функция в коде "вспомогательной функции" и новое перо, чтобы детализировать все, что я пробовал / яв настоящее время пытается на основе обратной связи: https://codepen.io/willstocks_tech/pen/YBEzLW?editors=1012

Текущий код:

function lMS(f) {
    if(Array.isArray(f)) {
        var urlen = f.length;
        for (var u = 0; u < urlen; u++) {
            var uri = f[u];
            if(uri !== null && uri !== '') {
                return new Promise(
                    function(resolve, reject) {
                        var thescript = document.createElement('script');
                        thescript.src = encodeURI(uri);
                        document.body.appendChild(thescript);
                        thescript.onerror = function(response) {
                            return reject("Loading the script failed!", response);
                        } 
                        thescript.onload = function() {
                            return resolve("Script setup and ready to load!");
                        } 
                    }
                )
            } else {
                return new Promise( //pretty sure this could just be Promise.resolve();
                    function(resolve, reject) {
                        return resolve ("No script to load");
                    }
                )
            }
        }
    } else {
        if(f !== null && f !== '') {
            return new Promise(
                function(resolve, reject) {
                    var thescript = document.createElement('script');
                    thescript.src = encodeURI(f);
                    document.body.appendChild(thescript);
                    thescript.onerror = function(response) {
                        return reject("Loading the script failed!", response);
                    } 
                    thescript.onload = function() {
                        return resolve("Script setup and ready to load!");
                    } 
                }
            )
        } else {
            return new Promise( //pretty sure this could just be Promise.resolve();
                function(resolve, reject) {
                    return resolve ("No script to load");
                }
            )
        }
    }
}

Новая работа в процессе (с помощником):

function pL(e, f, g) {
    cNS(e).then(
        function() {
            lMS(f, g)
        }
    ).catch(function(error){return error})
    }
}

function lMS(f, g) {
    var w = [];
    if(Array.isArray(f)) {
        var urlen = f.length;
        for (var u = 0; u < urlen; u++) {
            var uri = f[u];
            if(uri !== null && uri !== '') {
                uriProm(uri); //go and get a script that is needed
                w.push(uri);  //maybe push to array and return resolve once everything is done?
            } else {
                return;
            }
        }
        if(w.length === url.length && w.every(function(value, index) { return value === url[index]})) {
            console.log("We've made it to here");
            return init(g) //go off to run a piece of code based reliant on the script of uriProm
            }
    } else { //not an array of values
        if(url !== null && url !== '') {
            uriProm(uri);
            return init(g)
        } else {
            return
        }
    }
}

//helper function (avoiding duplicate code)
function uriProm(uri){
    var thescript = document.createElement('script');
    thescript.src = encodeURI(uri);
    document.body.appendChild(thescript);
    thescript.onerror = function(response) {
        return reject("Loading the script failed!", response);
    } 
    thescript.onload = function() {
        return Promise.resolve();
    } 
}

    function init(g) {
        if(Array.isArray(g)) {
            var fnlen = g.length;
            for (var f = 0; f < fnlen; f++) {
                try {
                    new Function(g[f])();
                } catch(err) {
                    console.error('There was an error: ', err.name, err.stack);
                }
            }           
        } else {    
            try {
                new Function(g)();
            } catch(err) {
                console.error('There was an error: ', err.name, err.stack);
            }
        }
    }

1 Ответ

0 голосов
/ 08 февраля 2019

После нескольких дней попыток и тонны исследований я выяснил, как я могу это сделать.

Использование Array.forEach для итерации по значениям массива (вместо попытки цикла for) означает, что я могуотправьте каждое обещание в массив, а затем Promise.all в массиве!:)

//This won't run in JSFiddle because the rest of the function doesn't exist
//https://github.com/willstocks-tech/dynamically-polyfill-features-for-a-script/releases - 0.0.5-beta.6

function lMS(f, g) {
  if (Array.isArray(f)) { //Check whether array is being passed or just string
    var promises = []; //Gotta catch 'em all... as an array
    f.forEach( //iterate through the array using Array.forEach()
      function(f) { //pass each item in the array through to the "get script" function
        promises.push(nbU(f)) //push the resolve/reject into the promises array
      }
    );
    Promise.all(promises) //Make sure that all promises that are returned come back as resolved
      .then( //then
        () => init(g) //run the init function!
      );
  } else if (!Array.isArray(f) && f !== null && f !== '') { //if not an array and not blank values
    return nonblankURL(f) //resolve or reject getting the script
      .then( //then
        () => init(g) //run the init function!
      )
  } else { //not array, blank values
    return init(g); //straight to init because no dependency (blank)
  }
}

Я могу подтвердить, что это работает, как и ожидалось!https://codepen.io/willstocks_tech/pen/YBEzLW?editors=1012

Я немного больше понимаю, как выполнять обещания / асинхронное выполнение кода :) Спасибо @Bergin за помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...