我是否可以使用promises加载iframe?

时间:2015-08-18 08:36:06

标签: javascript promise es6-promise

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

有了承诺,我应该能够做得更好。加载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赞赏。

1 个答案:

答案 0 :(得分:1)

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

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