我将HTML(外部应用)加载到iFrame
当我的callback
中的元素可用时,我想“做”某事(iFrame
)。这是我写它的方式,我想用Promises写这个:
function doWhenAvailable(selector, callback) {
console.warn("doWhenAvailable", selector)
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
callback && callback(elt);
} else {
setTimeout(function() {
doWhenAvailable(selector, callback);
}, 1000);
}
}
实际上,我不想使用setTimeout
,而是使用setInterval
重复“查找元素”,直到找到并解决“承诺”。
答案 0 :(得分:2)
不,你不会使用setInterval
,你只需将超时包装在一个承诺中并放弃回调:
function wait(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
function whenAvailable(selector) {
var elt = $('#myiFrame').contents().find(selector);
if (elt.length)
return Promise.resolve(elt);
else
return wait(1000).then(function() {
return whenAvailable(selector);
});
}
答案 1 :(得分:1)
保持你的递归风格,它会变成这样:
function doWhenAvailable(selector) {
var dfd = jQuery.Deferred();
console.warn("doWhenAvailable", selector)
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
return dfd.resolve(elt);
} else {
setTimeout(function() {
doWhenAvailable(selector).then(function(e) {
dfd.resolve(e);
});
}, config[env].wrapper.timeOutInMs);
}
return dfd.promise();
}
但我本来试图避免在这里进行递归调用
答案 2 :(得分:1)
一般的想法是返回一个承诺,而不是接收一个回调。
示例:
var xpto = function(res) {
return new Promise((resolve, reject) => {
if(res > 0) resolve('Is greater');
else reject(new Error('is lower'));
});
}
所以在你的情况下:
function doWhenAvailable(selector) {
function work(callback) {
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
callback(elt);
}
}
return new Promise((resolve, reject) => {
console.warn("doWhenAvailable", selector)
setInterval(() => work(resolve), 1000);
})
}
答案 3 :(得分:0)
下面:
function doWhenAvailable(selector) {
return new Promise(function(resolve, reject){
console.warn("doWhenAvailable", selector)
if ($('#myiFrame').contents().find(selector).length) {
var elt = $('#myiFrame').contents().find(selector);
console.info("doWhenAvailable Found", elt)
resolve(elt);
} else {
setTimeout(function() {
doWhenAvailable(selector).then(function(data){
resolve(data);
});
}, config[env].wrapper.timeOutInMs);
}
}
}
然后像这样调用你的函数:
doWhenAvailable("#elemId").then(function(elt){
//do what you want
});