我可以,我应该使用 promises 加载 Iframe 吗?

Can I, Should I, use promises for loading an Iframe?

我们有一个活泼的小移动应用程序,有两个面板布局。容器页面提供框架,面板作为 Iframe 实现。我们喜欢 Iframe,因为它们创建了一个范围,对面板进行了分区,但是我们当前在面板之间进行通信的方法很糟糕。面板 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 的答案表示赞赏。

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

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