首页 文章

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

提问于
浏览
4

这个问题在这里已有答案:

我仍然是一个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'));

EDIT: function based on current feedback:

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

2 回答

  • 0

    正如Mike McCaughan所提到的,您可以使用 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'));
    
  • 5

    你可以尝试链接电话,因为承诺应该是,这有点做作但我希望你得到我的漂移:

    PS将全局对象附加到窗口是一个坏主意,如果可能的话,不应该这样做,这只是显示使用您的流程的快速示例...

    window.attempts = 0;
    window.maxAttempts = 10;
    window.globalThing = true;
    function 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!');
    }).then((pass) => {
        return pass;
      }, (fail) => {
        window.attempts ++;
        //If within attempts, try again
        if(window.attempts < window.maxAttempts){
          //Chain a new promise to resolve with a timeout of 500ms
          return new Promise((resolve, reject) => {
             setTimeout(() => {
                resolve()
             }, 500);
          }).then(() => {
             //Then try again
             return createSlot();
          })
        }
        else {
          //else fail out with reason
          return fail;
        }
      });
    }
    

相关问题