如何使用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 });