我们有一个快速的小型移动应用程序,具有两个面板布局。容器页面提供骨架,面板作为 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/