Last active
November 29, 2018 07:21
-
-
Save artivilla/a6c7cd7efcf91d79a9526ea38abdb258 to your computer and use it in GitHub Desktop.
JS Binpromise bin fun// source https://jsbin.com/jivusuz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="promise bin fun"> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<script id="jsbin-javascript"> | |
// return a promise resolving (or rejecting) in *time* | |
const delay = (() => { | |
let counter = 0; // incremental job id | |
let progress = {}; // keeps job ids that are being resolved | |
return (time) => { | |
counter++; | |
// job start | |
console.log('BEING PROCESSED: ' + Object.keys(progress).length); | |
console.log(`+ ${counter} START job`); | |
progress[counter] = true; | |
return new Promise((resolve, reject) => { | |
setTimeout(((i) => { | |
// job stop | |
console.log(`- ${i} END job`) | |
delete progress[i]; | |
const threshold = 1 // should it resolve or not? | |
if (Math.random() <= threshold) return resolve(i) // yes | |
else return reject(i); // no | |
}).bind(this, counter), time || Math.random() * 2000); // wait 0-2000ms | |
}); | |
}; | |
})(); | |
// return an array of jobs | |
const jobs = (number) => { | |
return [...Array(number).keys()].map(() => delay); | |
} | |
// write a class that throttles the concurrency and responds | |
// to the following interface | |
class Deferred { | |
constructor() { | |
this.promise = new Promise((resolve, reject)=> { | |
this.reject = reject | |
this.resolve = resolve | |
}) | |
} | |
} | |
class Queue{ | |
constructor({concurrency}) { | |
this.concurrency = concurrency; | |
this.jobs = []; | |
this.endCounter = 0; | |
this.dfd= new Deferred(); | |
} | |
add(...incomingJobs) { | |
this.endCounter = incomingJobs.length; | |
this.jobs = incomingJobs; | |
} | |
runNextJob() { | |
const job = this.jobs.shift(); | |
if (!job) { | |
return; | |
} | |
this.executeJob(job) | |
}; | |
executeJob(job) { | |
job() | |
.then(val => { | |
this.runNextJob(); | |
this.endCounter--; | |
if (this.endCounter === 0) { | |
this.dfd.resolve(); | |
} | |
}) | |
.catch(err => console.log(Error('Job execution failed'))); | |
} | |
get onFinish() { | |
return this.dfd.promise; | |
} | |
start () { | |
for(let i=0;i<this.concurrency;i++){ | |
const job = this.jobs.shift(); | |
if (!job) { | |
return; | |
} | |
this.executeJob(job) | |
} | |
} | |
} | |
let queue = new Queue({concurrency: 10}) | |
queue.add(...jobs(3)); | |
queue.onFinish.then(() => console.log('Aloha!')); | |
queue.start(); | |
</script> | |
<script id="jsbin-source-javascript" type="text/javascript">// return a promise resolving (or rejecting) in *time* | |
const delay = (() => { | |
let counter = 0; // incremental job id | |
let progress = {}; // keeps job ids that are being resolved | |
return (time) => { | |
counter++; | |
// job start | |
console.log('BEING PROCESSED: ' + Object.keys(progress).length); | |
console.log(`+ ${counter} START job`); | |
progress[counter] = true; | |
return new Promise((resolve, reject) => { | |
setTimeout(((i) => { | |
// job stop | |
console.log(`- ${i} END job`) | |
delete progress[i]; | |
const threshold = 1 // should it resolve or not? | |
if (Math.random() <= threshold) return resolve(i) // yes | |
else return reject(i); // no | |
}).bind(this, counter), time || Math.random() * 2000); // wait 0-2000ms | |
}); | |
}; | |
})(); | |
// return an array of jobs | |
const jobs = (number) => { | |
return [...Array(number).keys()].map(() => delay); | |
} | |
// write a class that throttles the concurrency and responds | |
// to the following interface | |
class Deferred { | |
constructor() { | |
this.promise = new Promise((resolve, reject)=> { | |
this.reject = reject | |
this.resolve = resolve | |
}) | |
} | |
} | |
class Queue{ | |
constructor({concurrency}) { | |
this.concurrency = concurrency; | |
this.jobs = []; | |
this.endCounter = 0; | |
this.dfd= new Deferred(); | |
} | |
add(...incomingJobs) { | |
this.endCounter = incomingJobs.length; | |
this.jobs = incomingJobs; | |
} | |
runNextJob() { | |
const job = this.jobs.shift(); | |
if (!job) { | |
return; | |
} | |
this.executeJob(job) | |
}; | |
executeJob(job) { | |
job() | |
.then(val => { | |
this.runNextJob(); | |
this.endCounter--; | |
if (this.endCounter === 0) { | |
this.dfd.resolve(); | |
} | |
}) | |
.catch(err => console.log(Error('Job execution failed'))); | |
} | |
get onFinish() { | |
return this.dfd.promise; | |
} | |
start () { | |
for(let i=0;i<this.concurrency;i++){ | |
const job = this.jobs.shift(); | |
if (!job) { | |
return; | |
} | |
this.executeJob(job) | |
} | |
} | |
} | |
let queue = new Queue({concurrency: 10}) | |
queue.add(...jobs(3)); | |
queue.onFinish.then(() => console.log('Aloha!')); | |
queue.start(); | |
</script></body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// return a promise resolving (or rejecting) in *time* | |
const delay = (() => { | |
let counter = 0; // incremental job id | |
let progress = {}; // keeps job ids that are being resolved | |
return (time) => { | |
counter++; | |
// job start | |
console.log('BEING PROCESSED: ' + Object.keys(progress).length); | |
console.log(`+ ${counter} START job`); | |
progress[counter] = true; | |
return new Promise((resolve, reject) => { | |
setTimeout(((i) => { | |
// job stop | |
console.log(`- ${i} END job`) | |
delete progress[i]; | |
const threshold = 1 // should it resolve or not? | |
if (Math.random() <= threshold) return resolve(i) // yes | |
else return reject(i); // no | |
}).bind(this, counter), time || Math.random() * 2000); // wait 0-2000ms | |
}); | |
}; | |
})(); | |
// return an array of jobs | |
const jobs = (number) => { | |
return [...Array(number).keys()].map(() => delay); | |
} | |
// write a class that throttles the concurrency and responds | |
// to the following interface | |
class Deferred { | |
constructor() { | |
this.promise = new Promise((resolve, reject)=> { | |
this.reject = reject | |
this.resolve = resolve | |
}) | |
} | |
} | |
class Queue{ | |
constructor({concurrency}) { | |
this.concurrency = concurrency; | |
this.jobs = []; | |
this.endCounter = 0; | |
this.dfd= new Deferred(); | |
} | |
add(...incomingJobs) { | |
this.endCounter = incomingJobs.length; | |
this.jobs = incomingJobs; | |
} | |
runNextJob() { | |
const job = this.jobs.shift(); | |
if (!job) { | |
return; | |
} | |
this.executeJob(job) | |
}; | |
executeJob(job) { | |
job() | |
.then(val => { | |
this.runNextJob(); | |
this.endCounter--; | |
if (this.endCounter === 0) { | |
this.dfd.resolve(); | |
} | |
}) | |
.catch(err => console.log(Error('Job execution failed'))); | |
} | |
get onFinish() { | |
return this.dfd.promise; | |
} | |
start () { | |
for(let i=0;i<this.concurrency;i++){ | |
const job = this.jobs.shift(); | |
if (!job) { | |
return; | |
} | |
this.executeJob(job) | |
} | |
} | |
} | |
let queue = new Queue({concurrency: 10}) | |
queue.add(...jobs(3)); | |
queue.onFinish.then(() => console.log('Aloha!')); | |
queue.start(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment