Skip to content

Instantly share code, notes, and snippets.

@vanayun
Created May 4, 2019 12:31
Show Gist options
  • Save vanayun/436bcb3afa03f6165832c9cc7ca6b991 to your computer and use it in GitHub Desktop.
Save vanayun/436bcb3afa03f6165832c9cc7ca6b991 to your computer and use it in GitHub Desktop.
promise
// 순차 반복
function spiderLinks(currentUrl, body, nesting) {
let promise = Promise.resolve();
if(nesting === 0) {
return promise;
}
const links = utilities.getPageLinks(currentUrl, body);
links.forEach(link => {
promise = promise.then(() => spiderLinks(link, nesting - 1));
});
return promise;
}
// 순차 반복 - 패턴
let tasks = [/* ... */]
let promise = tasks.reduce((prev, task) => {
return prev.then(() => {
return task();
});
}, Promise.resolve());
promise.then(() => {
// 모든 작업들이 완료됨
});
// 병렬 실행
function spiderLinks(currentUrl, body, nesting) {
if(nesting === 0) {
return Promise.resolve();
}
const links = utilities.getPageLinks(currentUrl, body);
const promises = links.map(link => spiderLinks(link, nesting - 1));
return Promise.all(promises);
}
// 제한된 병렬 실행
// TaskQueue Class의 next() 함수 수정
next() {
while (this.running < this.concurrency && this.queueMicrotask.length) {
const task = this.queue.shift();
task().then(() => {
this.running--;
this.next();
});
this.running++;
}
}
// 수정된 spiderLinks
function spiderLInks(currentUrl, body, nesting) {
if(nesting === 0) {
return Promise.resolve();
}
const links = utilities.getPageLinks(currentUrl, body);
// 처리할 작업이 없는 경우, 다음 번에 만드는 Promise는 결정(settle)될 수 없기 때문에 다음과 같은 과정이 필요하다.
if(links.length === 0) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
let completed = 0;
let errored = false;
links.forEach(link => {
let task = () => {
return spider(link, nesting - 1)
.then(() => {
if(++completed === links.length) {
resolve();
}
}).catch(() => {
if(!errored) {
errored = true;
reject();
}
});
};
downloadQueue.pushTask(task);
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment