javascript - 我可以、应该使用 Promise 来加载 Iframe 吗?

标签 javascript promise es6-promise

我们有一个快速的小型移动应用程序,具有两个面板布局。容器页面提供骨架,面板作为 Iframe 实现。我们喜欢 Iframe,因为它们创建了一个范围,对面板进行了分区,但我们当前在面板之间进行通信的方法很糟糕。 Panel 1 在全局范围内分配其调用参数,然后调用 Panel2.location() 加载页面。 Panel2 的 onload 处理程序查找先前分配的调用参数,并执行其任务。如果出现 HTTP 错误,调用者永远不会知道,并且错误会直接显示在屏幕上。

有了 promise ,我应该能够做得更好。加载Panel2 是一个异步操作。我很想能够做到这一点...

Panel2.myAsynchLoad("myNewPage.html").then(
    function(myNewPage){
        myNewPage.someFunc( calling, parameters, passed, directly );
    },
    function(err){
        ...errors notified to caller
    }
);

但是在编写 myAsynchLoad() 时,我直接遇到了问题。如果我使用 location() 加载 panel2,我似乎无法检索 HTTP 错误。如果我使用 XmlHttpRequest 和 document.write(),则这不是正常的页面加载,并且新页面中的脚本不会注册。

有什么好的方法可以做到这一点吗?我首先应该来这里吗?不使用 jquery 的答案表示赞赏。

最佳答案

如果有人回到这里,我就实现了我的功能。我的解决方案是调用 url 两次。一旦使用 xmlHttpRequest 捕获任何错误,然后使用相同的 url 进行 window.location() 。如果缓存 header 设置正确,则将从浏览器缓存提供页面,而无需再次调用服务器。它允许我将页面视为对象,我可以在其上调用函数,并进行错误处理,所以是的,我认为这非常酷。

var waitingCaller = [];
function goP(panel, url) {
    return new Promise(function (resolve, reject) {
        //first retrieve via AJAX to put in browser cache and recover eventual errors
        getUrl(url).then(
            function (xhr) {
                //ignore the response and change location with same url
                waitingCaller[panel] = resolve; //We're not storing reject because we can't trap errors. From here we assume success.
                panels[panel].contentWindow.location = url;
            },
            function (err) { reject(err) }
        )
    });
}
function connectWaitingCaller(panel,event) {
    waitingCaller[panel](panels[panel].contentWindow); //Call resolve, passing window reference
    waitingCaller[panel] = null; //caller no longer waiting
}
panels[1].addEventListener("load", connectWaitingCaller.bind(this, 1));

使用它...

goP(1, "SomeNewPage.php")
.then( function(SomeNewPage){
    SomeNewPage.myFunc();
});

我的 getUrl 实用函数,使答案完整......

//requêtes HTTP avec Promises !
//returns xhr object, used by getUrlAsXXX() functions
function getUrl(url) {
    // Return a new promise.
    return new Promise(function (resolve, reject) {
        // Do the usual XHR stuff
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);

        xhr.onload = function () {
            // This is called even on 404 etc
            // so check the status
            if (xhr.status == 200) {
                // Resolve the promise with the request object
                // so downstream functions have full access.
                resolve(xhr);
            }
            else {
                // Otherwise reject with the status text
                // which will hopefully be a meaningful error
                reject(Error(xhr.status + " \"" + xhr.statusText + "\" while getting " + url));
            }
        };

        // Handle network errors
        xhr.onerror = function () {
            reject(Error("Network Error"));
        };

        // Make the request
        xhr.send();
    });
}

关于javascript - 我可以、应该使用 Promise 来加载 Iframe 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32067469/

相关文章:

javascript - 具有 6 个键的对象数组,如何将它们分组为更少的键?

javascript - 如何禁用 "background-attatchment: fixed"会导致错误

node.js - 在 Node.js 中使用 async/await 处理 promise 拒绝的正确方法是什么?

Javascript:无法将字符串转换为数字

javascript - React 中状态变量的顺序重要吗?

javascript - 并行调用一系列 Promise,但按顺序解决它们,而不等待其他 Promise 解决

javascript - 将 JavaScript Promise 结果添加到隐藏输入字段

javascript - 为什么等待 Selenium getAttribute 仍然返回一个 promise ?

javascript - Promise 可以保持 pending 状态多长时间?

javascript - ES6 Promise "pending"与 "fulfilled"