Created
April 8, 2019 06:37
-
-
Save AndrewThian/fa7d808b4bb7dccbdecbcd691d5c2d43 to your computer and use it in GitHub Desktop.
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
/* | |
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