如何在 Promise 函数中调用辅助函数

How to call a helper function within a Promise'd function

我还是 Javascript 的新手,我希望有人能帮助我解决我遇到的问题,我只是无法解决问题!!

我有一个包含很多重复代码的函数,因此尝试将其拆分为辅助函数。但是,当我从 lMS 函数(当前被称为 lMS(f).then()中调用辅助函数时,辅助函数在依赖于 lMS 执行和完成的 init(g) 函数之后执行。

由于我对 Promise 的工作方式和异步函数的性质的误解,我 99% 确定我遇到了这个问题。

我试过将重复的代码放入一个单独的函数中,并在需要时调用它。我已经尝试将其响应捕获为 Promises,或者将响应推送到一个数组中,然后仅在我返回所有项目时执行(与原始数组相比)。

以下是原始脚本,其中没有辅助函数但有大量重复代码:https://github.com/willstocks-tech/dynamically-polyfill-features-for-a-script/releases/tag/0.0.5b5 - 第57行(function loadMyScript(url) )

我已经把辅助代码放到了Codepen中(我已经研究了几天)https://codepen.io/willstocks_tech/pen/pGgRrG?editors=1012

更新

在 "helper function" 代码中包含 init 功能,并用一支新笔来详细说明我 tried/am 目前根据反馈尝试的所有内容: 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);
            }
        }
    }

经过几天的尝试和大量的研究,我找到了如何做到这一点。

使用 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

我对 Promises/asynchronous 代码执行有了更多的了解 :) 感谢@Bergin 提供的所有帮助