【发布时间】:2017-02-24 03:47:35
【问题描述】:
我仍然是一个 Promise 菜鸟,并且正在尝试弄清楚如何让我的 Promise 重演。
有一个 ES6 承诺,如果没有设置一些全局标志,则拒绝。我需要它每 500 毫秒重试一次,直到:
- 承诺返回一个解决方案,
- 或达到最大尝试次数(比如说 10 次)。
由于 Promise 是异步的,我真的不想使用 setInterval() 检查,因为我认为异步代码不能正常工作。一旦承诺成功解决(或超时),我需要立即终止检查。
我正在使用 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'));
编辑:基于当前反馈的函数:
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);
});
}
});
}
【问题讨论】:
-
研究“递归函数”。基本上,在
catch中,我建议等待(通过setTimeout)一段时间,然后再次调用componentDidMount。你不需要做任何特殊的“终止”,因为如果 promise 解决了它就不会被调用。 -
嗨@MikeMcCaughan,感谢您的帮助。所以我用这种方法看到的问题是,如果全局无法设置,它将永远调用。此外,在 React 中,
componentDidMount不应该被手动调用(尽管我们可以解决这个问题——我认为最大的问题是第一部分) -
是的,您只需要跟踪尝试次数。我想你可以弄清楚那部分:)。
标签: javascript promise ecmascript-6 es6-promise repeat