重复承诺,直到它没有被拒绝或达到超时

Pre*_*fix 4 javascript repeat promise ecmascript-6 es6-promise

我仍然是一个Promise noob,我正试图弄清楚如何让我的Promise重演.

如果没有设置某个全局标志,则拒绝ES6.我需要它每500ms重试一次,直到:

  • 承诺回归决心,
  • 或者达到最大尝试次数(比方说10).

由于Promise是异步的,我真的不想使用setInterval()检查,因为我不认为它可以正常使用异步代码.一旦promise成功解决(或达到超时),我需要检查终止.

我正在使用ES6 + React + ES6 Promises(所以请不要使用Q或Bluebird特定的答案!)

http://jsfiddle.net/2k2kz9r9/8/

// CLASS
class Test extends React.Component {
    constructor() {
      this.state = {
        status: 'setting up..',
      }
    }
    componentDidMount() {
      // TODO: how do I get this to loop with a timeout?
      this.createSlot()
        .then((slot) => {
          this.setState({
            status: slot
          });
        })
        .catch((e) => {
          this.setState({
            status: e.message
          });
        })
    }
    createSlot() {
      return new Promise((resolve, reject) => {
        if (!this.checkIsReady()) {
          reject(new Error('Global isnt ready yet'));
        }
        // more stuff here but going to resolve a string for simplicity sake
        resolve('successful!');
      });
    }
    checkIsReady() {
      return window.globalThing && window.globalThing === true;
    }
    render() {
        return ( <div>{this.state.status}</div> );
    }
}





    // RENDER OUT
    React.render(< Test/> , document.getElementById('container'));
Run Code Online (Sandbox Code Playgroud)

编辑:基于当前反馈的功能:

  createSlot(tries) {
    const _this = this;
    return new Promise(function cb(resolve, reject) {
      console.log(`${tries} remaining`);
      if (--tries > 0) {
        setTimeout(() => {
          cb(resolve, reject);
        }, 500);
      } else {
        const { divId, adUnitPath } = _this;
        const { sizes } = _this.props;

        // if it's not, reject
        if (!_this.isPubadsReady()) {
          reject(new Error('pubads not ready'));
        }
        // if it's there resolve
        window.googletag.cmd.push(() => {
          const slot = window.googletag
            .defineSlot(adUnitPath, sizes, divId)
            .addService(window.googletag.pubads());
          resolve(slot);
        });
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)

Mik*_*uck 5

正如迈克麦考恩所提到的,你可以用来setTimeout在尝试之间创造延迟.一旦成功或您的尝试用尽,请解决或拒绝您的承诺.

function createPromise(tries, willFail) {
  return new Promise(function cb(resolve, reject) {
    console.log(tries + ' remaining');
    if (--tries > 0) {
      setTimeout(function() {
        cb(resolve, reject);
      }, 500);
    } else {
      if (willFail) {
        reject('Failure');
      } else {
        resolve('Success');
      }
    }
  });
}

// This one will fail after 3 attempts
createPromise(3, true)
  .then(msg => console.log('should not run'))
  .catch(msg => {
    console.log(msg);
    
    // This one will succeed after 5 attempts
    return createPromise(5, false);
  })
  .then(msg => console.log(msg))
  .catch(msg => console.log('should not run'));
Run Code Online (Sandbox Code Playgroud)

  • Upvote,因为你提到了我的名字:). (2认同)