I'm currently developing for a custom browser, which pretty much runs plain ES5 with Promises and no support for non-native code at all. This browser was made to simulate the comportment of an specific hardware whose processing isn't anything close to great. Also, I have very short application size limits.
With this in mind and the task of showing different views within the same window, one at a time and only once each time the application is used, I've come out with the idea of reloading only an iframe instead of the whole page.
To do this, I wrote the next code:
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);
The idea behind it is pretty simple:
However, it bricks. Sometimes the iframe
just hasn't loaded in time, so when I define doc
it's body is empty and I pass undefined
on .importNode()
, blowing up the whole stuff. Thinking that it should be an asynchronous execution problem, I wrapped the function in Promises and end up with the code like it is but the problem stills.
I would like to know exactly what I'm getting wrong about Promises, why the code isn't working and how can I correct it, preferably without the use of setTimeout().
You can listen for the load
event on the <iframe>
to ensure the iframe is never 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;
});
}
Also, calling .bind
on your functions may also be cause to some of your issues.
Try instead .then(function(x) { return functionCall(x,p2,p3) });