重复一个Promise,直到它没有被拒绝或超时为止
Repeat a Promise until it's not rejected or reach a timeout
我仍然是一个承诺新手,我正在努力找出如何让我的承诺重复自己。
有一个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'));
EDIT:基于当前反馈的函数:
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);
});
}
});
}
正如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'));
您可以尝试链接调用,因为承诺应该是,这有点做作,但我希望您能理解我的意思:
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;
}
});
}
相关文章:
- 在流星上使用微信js-sdk时出现拒绝权限错误
- 在Nodejs中Express输入DEBUG=app时权限被拒绝/bin
- 使用优化器在慢速连接上加载main.js时需要js超时
- 简单的ES6承诺问题-交换解决和拒绝参数
- javascript第三个XMLHttpRequest被拒绝.但前两个是允许的
- 当浏览器控制台未打开时,为什么要求会导致Internet Explorer 9超时
- 在ES6 Promise中,我应该在解决/拒绝之前使用return吗
- 超时功能的性能
- 使用不同的超时对数组中的每个项目进行角度动画处理
- 设置第一次执行的超时
- Facebook FB.init”;访问被拒绝”;在Internet Explorer 11中
- node.js测试事件是否是在不使用超时的情况下使用sinon.js发出的
- 未处理的拒绝MongoError:无法连接到MongoDB中的服务器
- 使用javascript和随机暂停/超时快速循环文本
- Node.js solrProxy访问被拒绝
- 在promise中为回调添加超时并拒绝
- 链接超时会导致最后一次超时被拒绝
- 重复一个Promise,直到它没有被拒绝或超时为止
- 未处理的拒绝错误:超时:没有加载此页面上的所有资源
- 如果未授予/拒绝访问,则会超时