Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在一个房间里等待承诺_Javascript_Asynchronous_Promise_Jszip - Fatal编程技术网

Javascript 在一个房间里等待承诺

Javascript 在一个房间里等待承诺,javascript,asynchronous,promise,jszip,Javascript,Asynchronous,Promise,Jszip,我对承诺不熟悉。我知道一个人是怎么工作的 我有一个函数,可以将包含外部引用(图像、样式、脚本)的html文档转换为嵌入这些资源的文件。它需要从异步源(JSZip实例)读取资源 我希望函数仅在所有承诺zip.file().async()之后返回。然后(…)被解析。例如,创建一个domDocument,然后对其执行一系列异步步骤,然后选择修改后的domDocument。可以修改调用此函数的区域以使用然后(例如处理文件(文件夹、zip、节点、dom)。然后(函数(结果)…如果需要) // folder

我对承诺不熟悉。我知道一个人是怎么工作的

我有一个函数,可以将包含外部引用(图像、样式、脚本)的html文档转换为嵌入这些资源的文件。它需要从异步源(JSZip实例)读取资源

我希望函数仅在所有承诺
zip.file().async()之后返回。然后(…)
被解析。例如,创建一个
domDocument
,然后对其执行一系列异步步骤,然后选择修改后的
domDocument
。可以修改调用此函数的区域以使用
然后
(例如
处理文件(文件夹、zip、节点、dom)。然后(函数(结果)
…如果需要)

// folder is set elsewhere
// zipObject is a JSZip instance
// node is an xml document which contains path references to files mentioned in the html
// domDocument is a DOMParser instance which is the html file

// these are the queryselectors for elements I want to match and replace in the html
[
    {"selector":"script[src]:not([src*='//'])","attribute":"src","type":"string"},
    {"selector":"link[href$='.css']:not([href*='//'])","attribute":"href","type":"string"},
    {"selector":"img:not([src*='//'])","attribute":"src","type":"base64"},
    {"selector":"a[target='_blank']:not([href*='://'])","type":"link"}
].forEach(function(element) {

    // grab all instances of a particular selector
    [].forEach.call(domDocument.querySelectorAll(element.selector), function(instance) {

        if (element.type === "link") { // replace link with plain text
            var tNode = document.createTextNode(instance.textContent);
            instance.parentNode.replaceChild(tNode, instance);

        } else { // need to load from the linked document
            var value = unescape(instance.getAttribute(element.attribute)),
                    path = null;

                // images that are already encoded can be ignored
                if (element.type==="base64" && (-1!==value.indexOf("data:image"))) return;

            if (value.indexOf("../")==0) { // resolve dependancy filename
                var dep = node.parentNode.querySelector("dependency");
                if (null !== dep) {
                    var ref = node.parentNode.parentNode.querySelector("resource[identifier='" + dep.getAttribute("identifierref") + "']");
                    if (null !== ref) {
                        path = ref.querySelector("file[href]").getAttribute("href");
                    }
                }
            } else { // resolve path from filename
                path = folder + value;
            }

            // perform the (asynchronous) modification of the document
            zipObject.file(path).async(element.type).then(function success(content) {
                if (element.attribute === "href") {
                    // <link href="file.css"> ==> <style>(file contents)</style>
                    var style = document.createElement("style");
                    style.appendChild(document.createTextNode(content));
                    instance.parentNode.replaceChild(style,instance);
                } else if (element.type === "base64") {
                    // <img src="file.gif"> ==> <img src="data:image/gif;base64,(image-contents)">
                    var extn = value.substr(value.lastIndexOf(".") + 1).toLowerCase();
                    instance.setAttribute("src", "data:image/" + extn + ";base64," + content);
                } else {
                    // <sript src="file.js"></script> => <script>(file-contents</script>)
                    instance.removeAttribute(element.attribute);
                    instance.appendChild(document.createTextNode(content));
                }
            }, function error (e) {
                console.log("ConvertZipForHtml Error", e);
                // leave it alone I guess
            });
        }
    });
});

// want this to return the MODIFIED version of the string
return domDocument;

仍然掌握async和Promission中的概念

@Bergi我真的看不出如何将链接上的代码合并到我的问题中。简而言之:收集在数组中的循环体中创建的所有承诺,然后调用
Promise。所有这些承诺都
。在我的例子中,承诺是从zip.aft中加载文件的输出呃加载内容后,它会替换外部循环中引用的元素。我如何在promise.all中引用这些变量?正如Bergi所说,使用promise.all会等待promise数组的所有成员都被解析或拒绝,在这种情况下,它会返回一个错误,您需要catch@Bergi我可以“我真的不知道如何将链接上的代码与我的问题结合起来。简言之:收集在数组中循环体中创建的所有承诺,然后调用
Promise。所有这些承诺都是
。在我的情况下,承诺是从zip中加载文件的输出。加载内容后,它会替换引用的元素。”在外部循环中。我如何在promise.all中引用这些变量?正如Bergi所说,使用promise.all将等待promise数组的所有成员被解析或拒绝,在这种情况下,它将返回一个您需要捕获的错误
function myFunction(args) {
    function replaceElements(elements) {
        return Promise.all(elements.map(selectElements));
    }

    function selectElements(element) {
        return new Promise(function (resolve, reject) {
            var myNodeList = domDocument.querySelectorAll(element.selector);
            for (var i = myNodeList.length; i--;) { // (generally is faster than forwards!)
                var instance = myNodeList[i];
                // -- snip --
                zipObject.file(path).async(element.type).then(function success(content) {
                    // -- snip --
                    resolve(instance);
                })
            }
        });
    }

    return replaceElements([
        {"selector":"script[src]:not([src*='//'])", "attribute":"src", "type":"string"},
        {"selector":"link[href$='.css']:not([href*='//'])", "attribute":"href", "type":"string"},
        {"selector":"img:not([src*='//'])", "attribute":"src", "type":"base64"},
        {"selector":"a[target='_blank']:not([href*='://'])", "type":"link"}
    ]);
}