我们有一个带有两个面板布局的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赞赏。
答案 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();
});
}