Skip to content

Instantly share code, notes, and snippets.

@AndrewThian
Created April 8, 2019 06:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrewThian/fa7d808b4bb7dccbdecbcd691d5c2d43 to your computer and use it in GitHub Desktop.
Save AndrewThian/fa7d808b4bb7dccbdecbcd691d5c2d43 to your computer and use it in GitHub Desktop.
/*
Task:
- request all files asynchronously
- print them out in order of file1 > file2 > file3
- print result as soon as it returns
- after all done, print "Completed!"
- only rely on promise without any promise helper (i.e Promise.all)
*/
// ======= implementation 1 ======== //
const fetchedFiles = {
file1: { status: 'NOT_FETCHED', data: null },
file2: { status: 'NOT_FETCHED', data: null },
file3: { status: 'NOT_FETCHED', data: null },
}
let fileCount = 0;
function fakeAjax(url,cb) {
var fake_responses = {
"file1": "The first text",
"file2": "The middle text",
"file3": "The last text"
};
var randomDelay = Math.round(Math.random() * 1E4);
console.log("Requesting: " + url);
setTimeout(function(){
cb(fake_responses[url]);
},randomDelay);
}
function output(file) {
file.status = 'PRINTED'
console.log(file.data);
}
function checkStatus(statusKey) {
const x = Object.values(fetchedFiles).reduce((acc, obj) => {
if (obj.status === statusKey) {
return acc + 1
}
return acc;
}, 0)
return x
}
function getFile(filename) {
/* body of getFile? */
fakeAjax(filename, (data) => {
fileCount++;
fetchedFiles[filename].status = 'FETCHED';
fetchedFiles[filename].data = data;
for (const key of Object.keys(fetchedFiles)) {
if (fetchedFiles[key].status === 'NOT_FETCHED') {
continue;
} else if (fetchedFiles[key].status === 'PRINTED') {
continue;
} else {
output(fetchedFiles[key]);
}
}
// if (fileCount === checkStatus('PRINTED')) {
// return console.log('Completed!')
// }
// if (fileCount === 1) {
// return output(fetchedFiles[filename]);
// }
})
}
// getFile('file2');
getFile('file3');
getFile('file1');
// ======= implementation 2 ======== //
const NOT_FETCHED = 'NOT_FETCHED';
const FETCHED = 'FETCHED';
const PRINTED = 'PRINTED';
// alternative: use single object that stores content and status instead of two arrays
const filesStatus = Array(3).fill(NOT_FETCHED); // [NOT_FETCHED, NOT_FETCHED, NOT_FETCHED]
const filesContent = Array(3).fill(null);
const fetchFileCallback = (content, fileId) => {
// update file status and content
filesStatus[parseInt(fileId) - 1] = FETCHED;
filesContent[parseInt(fileId) - 1] = content;
// print if applicable
for (let i = 0; i < 3; i++) {
if (filesStatus[i] === NOT_FETCHED) {
break;
} else if (filesStatus[i] === PRINTED) {
continue;
} else if (filesStatus[i] === FETCHED) {
print(filesContent[i]);
filesStatus[i] = PRINTED;
if (i === 2) print('Done');
}
}
}
function fetchFile(url, cb) {
var responses = {
"file1": "Content 1",
"file2": "Content 2",
"file3": "Content 3",
};
var randomDelay = Math.round(Math.random() * 1000);
setTimeout(function wait() {
cb(responses[url], url[url.length - 1]);
}, randomDelay);
}
function print(msg) {
console.log(msg);
}
function getFile(filename) {
fetchFile(filename, fetchFileCallback);
}
getFile('file1')
getFile('file2')
getFile('file3')
// ========= implemenation 3 ========= //
import { addListener } from "cluster";
const randomDelay = () => Math.floor(Math.random() * 10) + 1
const returnedData = {
file1: null,
file2: null,
file3: null
}
function fetchFile(url, cb) {
const data = {
"file1": "content1",
"file2": "content2",
"file3": "content3"
}
setTimeout(() => {
cb(url, data[url])
}, randomDelay())
}
class EventEmitter {
listeners = [];
internalValue = 0;
constructor () {
this.internalValue = 0;
}
emit(payload) {
for (const listener of this.listeners) {
listener(payload)
}
}
addListener(callback) {
this.listeners.push(callback)
}
}
function getFile(filename) {
fetchFile(filename, (url, data) => {
// if url name is file 1 should always return first
if (url === "file1") {
returnedData[url] = data
console.log(data)
return
}
// if url is file 2 should check if file 1 has been logged
// if not, wait for file 1 to be logged
// if (url === "file1") {
// returnedData[url] = data
// return console.log(data)
// } else if (url === "file2") {
// returnedData[url] = data
// if (returnedData.file1) {
// return console.log(returnedData.file1, data)
// }
// } else if (url === "file3") {
// returnedData[url] = data
// if (returnedData.file1 && returnedData.file2) {
// return console.log(returnedData.file1, returnedData.file2, data)
// }
// }
})
}
getFile("file1")
getFile("file2")
getFile("file3")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment