Skip to content

Instantly share code, notes, and snippets.

@inkless
Last active June 2, 2016 05:44
Show Gist options
  • Save inkless/9d498ca53e3a73fec3f1168de4684743 to your computer and use it in GitHub Desktop.
Save inkless/9d498ca53e3a73fec3f1168de4684743 to your computer and use it in GitHub Desktop.
/**
* An example to try to call API multiple times
*/
'use strict';
const maxTryTimes = 3;
const tryTimeInterval = 500;
/**
* try multiple times to access server API
* @return {Promise}
*/
function tryMultiTimesToServer() {
const server = new Server();
let currentTryTime = 0;
function tryServer(resolve, reject) {
++currentTryTime;
if (currentTryTime > maxTryTimes) {
return reject('exceed max times');
}
const delayTime = currentTryTime === 1 ? 0 : tryTimeInterval;
console.log(`\ntry to fetch data from server ${currentTryTime} time...`);
callApiWithWrapper(server, delayTime)
.then(data => {
if (data.success) {
resolve(data.data);
} else {
if (data.err === 'rate limit') {
tryServer(resolve, reject);
} else {
reject(data.err);
}
}
});
}
return new Promise(tryServer);
}
/**
* Call API with a wrapper to adapt promise and delay the request
*
* We have to have a wrapper to deal with the original API call,
* cuz we cannot chain promise' reject
* @param {Number} delayTime
* @return {Promise}
*/
function callApiWithWrapper(server, delayTime) {
return new Promise((resolve, reject) => {
delay(() => {
server.fetch()
.then(data => {
resolve({
success: true,
data,
});
})
.catch(resp => {
resolve({
success: false,
err: resp.err,
});
});
}, delayTime);
});
}
function delay(callback, delayTime) {
if (delayTime === 0) {
callback();
} else {
setTimeout(callback, delayTime);
}
}
// this is a mock for server API
class Server {
constructor(hitRateLimitProbability = 0.5, downProbability = 0.15) {
this.hitRateLimitProbability = hitRateLimitProbability;
this.downProbability = downProbability;
}
random(probability) {
return Math.random() < probability;
}
fetch() {
console.log('SERVER_RESPOND: server receive request...');
return new Promise((resolve, reject) => {
setTimeout(() => {
// check if server is down
if (this.random(this.downProbability)) {
console.log('SERVER_RESPOND: server down...');
return reject({
err: 'server down',
});
}
// check rate limit
if (this.random(this.hitRateLimitProbability)) {
console.log('SERVER_RESPOND: rate limit...');
return reject({
err: 'rate limit',
});
}
console.log('SERVER_RESPOND: server data!!!');
return resolve({
data: 'server data',
});
});
});
}
}
// test code
tryMultiTimesToServer()
.then(data => {
console.log('\nOUTPUT:', data);
})
.catch(err => {
console.log('\nOUTPUT:', err);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment