我目前正在开发一个自定义浏览器,它几乎使用Promises运行普通的ES5,并且根本不支持非本机代码。该浏览器用于模拟特定硬件的组合,其处理不是很接近。另外,我的应用程序大小限制很短。
考虑到这一点以及在同一个窗口中显示不同视图的任务,每次只使用一次应用程序,我只想重新加载iframe而不是整个页面。
为此,我编写了下一个代码:
function loadFrame(page){
return new Promise(function(resolve, reject){
var iframe = document.createElement('iframe');
iframe.classList.add('hidden');
iframe.src = page;
resolve(iframe);
});
}
function appendTo(elem, parentId){
return new Promise(function(resolve, reject){
var parentNode = document.getElementById(parentId);
parentNode.appendChild(elem);
resolve(elem);
});
}
function robOf(elem, id){
return new Promise(function(resolve, reject){
var parent = elem.parentNode;
var doc = elem.contentDocument; // body hasn't loaded so...
var toImport = doc.getElementById(id); // ... this returns undefined...
var imported = parent.importNode(toImport, true); //... thus breaking it here
parent.removeChild(elem);
resolve(imported);
});
}
loadFrame('example/myPage.htm')
.then(function(elem){ return appendTo(elem, 'myParentId') })
.then(function(parent){ return robOf(parent, 'myElemId') })
.then(doSomething);
它背后的想法非常简单:
但是,它砖。有时iframe
没有及时加载,所以当我定义doc
时它的身体是空的,我在undefined
上传递.importNode()
,炸掉了整个东西。认为它应该是一个异步执行问题,我将函数包装在Promises中并最终得到代码,但问题仍然存在。我想确切地知道我对Promises的错误,为什么代码不起作用以及如何纠正它,最好不使用setTimeout()。
你可以在load
上听<iframe>
事件,以确保iframe绝不是undefined
。
function loadFrame(page){
return new Promise(function(resolve, reject){
var iframe = document.createElement('iframe');
iframe.addEventListener('load', function(e) {
resolve(this);
});
iframe.classList.add('hidden');
iframe.src = page;
});
}
此外,在您的功能上调用.bind
也可能导致您的一些问题。
尝试改为.then(function(x) { return functionCall(x,p2,p3) });