如何使用Promises编写我的函数

时间:2017-03-08 13:53:56

标签: javascript jquery iframe promise

我将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重复“查找元素”,直到找到并解决“承诺”。

4 个答案:

答案 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
});