如何使用Promises编写我的函数
我将HTML(外部应用程序)加载到iFrame
当一个元素在我的iFrame
可用时,我想“做”某些事情( callback
)。 这是我写它的方式,我想用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
重复“find element”,直到找到并解决“promise”。
不,你不会使用setInterval
,你只需将超时包装在一个promise中并删除回调:
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); }); }
保持你的递归风格,它会变成这样的:
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(); }
但我本来试图避免递归调用
一般的想法是返回一个承诺而不是接收回调。
例:
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); }) }
这里:
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 });