중복 JS 코드를 고차 함수로 변환
Aug 20 2020
재사용되는 코드 블록이 있으며이 중복을 제거하기 위해 함수형 프로그래밍을 사용하고 싶습니다.
내 코드는 항목의 배열을 가져 와서 항목을 500 개의 일괄 처리로 분할 한 다음 일종의 작업을 수행합니다.
첫 번째 기능에서는 데이터베이스에서 항목을 삭제합니다.
삭제 기능 :
const deleteDocuments = async (documentReferences) => {
const batchesOf500 = Math.ceil(documentReferences.length / 500);
for(let batchNumber = 0; batchNumber < batchesOf500; batchNumber += 1) {
const batch = getBatchWriter();
const startingIndex = batchNumber * 500;
const maxIndex = startingIndex + 500;
for(let index = startingIndex; index < maxIndex; index += 1) {
if(index < documentReferences.length) {
const documentPath = documentReferences[index];
batch.delete(documentPath);
}
}
await batch.commit();
}
}
두 번째 함수는 거의 동일하지만 데이터베이스에서 삭제하는 대신 데이터베이스에 씁니다.
기능 추가 :
const writeToCollection = async (dataArray, collectionRef) => {
const batchesOf500 = Math.ceil(dataArray.length / 500);
for(let batchNumber = 0; batchNumber < batchesOf500; batchNumber += 1) {
const batch = getBatchWriter();
const startingIndex = batchNumber * 500;
const maxIndex = startingIndex + 500;
for(let index = startingIndex; index < maxIndex; index += 1) {
if(index < dataArray.length) {
const [key, value] = dataArray[index];
const doc = getDocFromPath(key);
batch.set(doc, value);
}
}
}
await batch.commit();
}
}
이 함수는 거의 동일하므로 대부분의 다리 작업을 수행하기 위해 고차 함수를 작성했습니다.
고차 기능 :
const runFunctionInBatchesOf500 = (func, dataArray) => {
const batchesOf500 = Math.ceil(dataArray.length / 500);
for(let batchNumber = 0; batchNumber < batchesOf500; batchNumber += 1) {
const batch = this.firestore.batch();
const startingIndex = batchNumber * 500;
const maxIndex = startingIndex + 500;
for(let index = startingIndex; index < maxIndex; index += 1) {
const document = dataArray[index];
func(document, batch);
}
}
await batch.commit();
}
그리고 각 문서에 적용 할 고유 한 기능을 만들고 다음과 같이 사용할 수 있습니다.
const write = (document, batch) => {
const doc = getDocFromPath(key);
batch.set(doc, value);
};
await runFunctionInBatchesOf500(write, dataArray);
이 모든 것이 작동하지만 뭔가 빠진 것 같습니다. 이것은 고차 함수를 효율적으로 사용합니까? 더 우아한 FP 스타일 솔루션은 무엇일까요?
답변
6 konijn Aug 20 2020 at 14:59
짧은 리뷰에서;
- 배치 길이를 500으로 하드 코딩하는 이유는 무엇입니까?
- 배치 길이가 좋은 상수가 아닌 이유는 무엇입니까?
- 함수 이름에 길이를 하드 코딩했습니다. 정말 불행합니다.
batchNumber++
보다 정식batchNumber += 1
- 나는 위해 갔을 것입니다
maxIndex = Math.min(startingIndex + 500, dataArray.length);
지금 당신이 전화를 많이 가지고 있기 때문에func
와undefined
A와document
값 await
필요runFunctionInBatchesOf500
합니다async
(지금 누락되었습니다)- 내가 사용하는 것이
Array.prototype.slice()
배열로 배치를 생성하고 사용하는forEach
각 슬라이스 / 배치에 const doc = getDocFromPath(key);
<-어디에서key
온 사악한 세계?
저는 개인적으로 Array 프로토 타입을 조정하여 FP 스타일을 계속 연결할 수 있도록 약간 사악 할 것입니다.
Array.prototype.mapSlice = function arrrayMapSlice(n){
//Just return `this` if we get a non-sensical parameter
if(isNaN(n) || n <= 0){
return this;
}
let start = 0, out = [];
while(start < this.length){
out.push(this.slice(start, start+=n));
}
return out;
}
async function runBatches(list, f, batchSize){
batchSize = batchSize || 500;
list.mapSlice(batchSize).forEach(batch => {
const firestoreBatch = this.firestore.batch();
batch.forEach(document => f(document, firestoreBatch ));
});
await batch.commit();
}