구현이 배울 수있는 약속을 사용하여 좋은 디자인에서 고려해야 할 몇 가지가 있습니다에 코드 구조를 변경하는 경우 :
- 최저 수준에서 promise ("promisify"라고 함)를 만듭니다. 동기화 작업. 그런 다음 약속 기능을 사용하여 논리 흐름을 제어하고 오류를 전파 할 수 있으며 코드가 약속으로 일관되게 구현됩니다. 이 경우
readFile()
을 반드시 알려야 함을 의미합니다. 또한 readFile()
을 프로젝트 나 향후 프로젝트에서 더욱 유용하게 만듭니다.
- 항상 오류를 올바르게 전파하는지 확인하십시오. 약속을 사용하지 않을 때 비동기 코드를 사용하면 원래 호출자에게 오류를 제대로 가져 오기가 어려울 수 있습니다. 특히 비동기 논리가 복잡해지면 (중첩 또는 시퀀스 작업으로) 복잡합니다.
- 비동기 작업이 시퀀스 여야하는지 또는 병렬로 실행할 수 있는지 여부를 신중하게 고려하십시오. 한 작업이 다른 작업에 종속되지 않고 여러 요청으로 일부 서비스에 과부하가 걸리지 않으면 병렬 처리를 통해 결과를 더 빠르게 얻을 수 있습니다.
- 호출자는 작업이 완료된 시점을 알 수 있고 비동기 결과에 액세스 할 수 있도록 비동기 함수로부터의 약속을 반환합니다.
- 기존 약속을 불필요하게 다른 약속으로 만들지 마십시오 (약속 방지 패턴 중 하나로 간주).
- jQuery 약속을 사용하는 경우 약속 표준과 호환되는 jQuery 기능을 계속 사용하여 향후 상호 운용성 문제가 발생하지 않도록하고 표준 약속이 작동하는 방식을 더 잘 알고있는 독자의 코드를 혼동하지 않도록하십시오.
이 모든 것을 감안할 때 표준 약속을 사용하고 jQuery 약속을 사용하고 작업 순서를 사용하거나 병렬로 실행하고 Bluebird 약속을 사용하여 코드를 구현하는 5 가지 방법이 있습니다. 모든 경우에 결국 순서대로 배열을 얻게됩니다.
Promisify readFile()
사용하여 표준 약속
먼저, "promisify"하자 당신이 다음 일을 제어 할 약속 로직을 사용할 수 있도록 ReadFile을 작업.표준 약속
function readFile(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function(e) {
resolve(e.target.result);
};
reader.onerror = reader.onabort = reject;
reader.readAsBinaryString(file);
});
}
, 병렬로 모든 파일 작업을 실행하려면 모든 결과를 반환하고 표준 약속을 사용하려면 병렬
의 모든 동작을, 당신은이 작업을 수행 할 수 있습니다
function readmultifiles(files) {
return Promise.all(files.map(readFile));
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
표준 약속으로 모든 작업은 순서대로 수행됩니다.
모든 파일 작업을 순차적으로 실행하려면 (원래 코드가 순차적으로 작업 했음에도 불구하고 모든 작업이 개별적이기 때문에 여기에서 수행해야하는 것처럼 보이지 않음) 모든 결과를 순서대로 반환하고 표준 약속을 사용할 수 있습니다. 이 작업을 수행. 여기에,
function readmultifiles(files) {
var results = [];
files.reduce(function(p, file) {
return p.then(function() {
return readFile(file).then(function(data) {
// put this result into the results array
results.push(data);
});
});
}, Promise.resolve()).then(function() {
// make final resolved value be the results array
return results;
});
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
그리고 : 시퀀싱
이를 다소 표준 설계 패턴은 체인의 순서 아래로 한 번에 하나씩 실행되도록 함께 배열 체인 모든 작업을 통해 시퀀스 .reduce()
를 사용 그것은 jQuery를 jQuery를 약속 사용
Promisify readFile()
을 약속 사용하여 어떻게 보일지 :
function readFile(file) {
return new $.Deferred(function(def) {
var reader = new FileReader();
reader.onload = function() {
def.resolve(e.target.result);
};
reader.onerror = reader.onabort = def.reject;
reader.readAsBinaryString(file);
}).promise();
}
jQuery를 가진 병렬 실행 :
function readmultifiles(files) {
return $.when.apply($, files.map(readFile));
}
// sample usage
readmultifiles(arrayOfFiles).then(function() {
var results = Array.prototype.slice(arguments);
// all results in the results array here
});
그리고는, 완성도, jQuery를
function readmultifiles(files) {
var results = [];
files.reduce(function(p, file) {
return p.then(function() {
return readFile(file).then(function(data) {
// put this result into the results array
results.push(data);
});
});
}, $.Deferred().resolve()).then(function() {
// make final resolved value be the results array
return results;
});
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
블루 버드 구현
으로 순차적으로 실행하고, I 약간을 사용하는 모습을 보여 줄 테니 more advanced promise library like Bluebird 그쪽으로 여기에 유용한 추가 기능이 있습니다. 병렬 코드와 readFile()
의 구현 표준 약속과 동일하지만, 순차적 구현을 위해, 그것은 순서 비동기 작업에 대한 몇 가지 내장 된 블루 버드 작업을 활용할 수 있으며, 단지 구성 것이다 :
function readmultifiles(files) {
return Promise.mapSeries(files, readFile);
}
// sample usage
readmultifiles(arrayOfFiles).then(function(results) {
// all results in the results array here
});
[이 질문에 대한 답변은 '$ .when()'] (http://stackoverflow.com/questions/25613624/q-promise-difference-between-when-and-then/25614136#25614136)과이 [Tried' $ .when()'및 행운 없음] (http://stackoverflow.com/questions/24549066/tried-when-and-then-no-lucky/24549220#24549220). 기본 비동기 작업이 완료되면 해결되는 일련의 약속을 전달해야합니다. 그것은 그 자체로 모든 것을 할 수있는 마법의 힘이 없습니다. 모든 일은 약속의 그룹을 감시합니다. 이 기능을 사용하려면 비동기 작업에서 약속을 사용하고 해결할 수 있습니다. – jfriend00
안녕 jFriend, 내 대답을 확인해 주시겠습니까? –