2017-12-13 1 views
1

promise에 싸여있는 코드가 있습니다. 이 코드는 원격 DB의 일부 레코드를 편집하고 편집 된 레코드 수를 반환합니다. 편집 된 레코드 수가 0보다 큰 경우 (즉, 일부 작업이 완료된 경우) 0이 다시 나타날 때까지 동일한 방법을 반복해서 실행하고 싶습니다. 즉, 더 이상 레코드를 편집 할 필요가 없습니다.이전 실행 결과에 따라 동일한 약속을 다시 실행할 수 있습니까?

여러 가지 방법을 시도했지만 모두 종료되지 않았기 때문에 (즉 해결되지 않았 음) 제대로 실행되지 않습니다.

첫 번째 버전은 내가 시도 :

const doEdits =() => { 
    return new Promise((resolve, reject) => { 
    someDB.performEdits() 
    .then(count => { 
     if (count > 0) { 
     doEdits() 
     } else { 
     resolve() 
     } 
    }) 
    .catch(reject) 
    }) 
} 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(doEdits) 
    .catch(reject) 
}) 

두 번째 버전은 내가 시도 :

const doEdits =() => { 
    return new Promise((resolve, reject) => { 
    someDB.performEdits() 
    .then(count => { 
     resolve(count) 
    }) 
    .catch(reject) 
    }) 
} 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(doEdits) 
    .then(count => { 
    if (count > 0) { 
     return doEdits() // 'doEdits()' did not work... 
    } else { 
     resolve() 
    } 
    }) 
    .catch(reject) 
}) 

일체의 제안을 환영합니다.

+0

'doEdits' 이후에 해결되지 않습니다. 약속은 항상 끝나면 '해결'또는 '거절'해야합니다. – Eric

+0

@ErikKralj, 첫 번째 예제에 대해 이야기하고 있다면'if (count> 0) '다음에'.then (...)'을 수행하고 반환 된 결과를 확인하고 몇 번이고 다시 ... –

답변

3

예, if 지점에서 resolve을 절대로 호출하지 않았습니다. 하지만 여기에 resolve 함수를 사용하면 안됩니다. Promise constructor antipattern! 그냥

function doEdits() { 
    return someDB.performEdits().then(count => { 
    if (count > 0) { 
     return doEdits(); 
    } else { 
     return undefined; // ??? 
    } 
    }); 
} 

return someDB.init().then(doEdits); 
+0

이것은 작동합니다! - 감사 –

1

가 스파게티를 확인하지 마십시오 할

당신은 정말 당신이 사용하는 기본 라이브러리가 이미 당신에게 promise.This 접근 방식을 반환 특히 이후, 약속의 무리를 만들 필요가 없습니다 모든 별도의 소스없이 목표를 달성해야한다 : 첫 번째 약속 후속 DB 호출에서

const doEdits = count => { 
    if(count > 0) { 
    return someDB.performEdits().then(doEdits); 
    } 
}; 

return someDB.init() 
    .then(() => { 
    performEdits().then(doEdits) 
    }); 

이 의지 체인 약속. 후속 then (및 catch)은 반환 된 약속에 따라 작동합니다 (즉, 해결 또는 거부 될 때까지 기다림). 전달되기 전에 해결 될 때 새로운 약속으로 대체 될 가능성이 있습니다. 당신이 약속을 인스턴스화하는거야 결정되면 코드가

작동하지 않은 이유는


, 당신은 해결 처리의 책임을 촬영하고 콜백을 거부 한 - 당신의 자신을 헌신 콜백 지옥에. 약속의 문제가 해결되어야 할 것과 정확히 일치합니다. 두 조각에서

는 최대한 빨리 count > 0을보고 doEdits에 전화, 당신은, 이전의 약속을 포기 새 인스턴스를, 당신의 여파로 취소 resolve D 약속의 흔적으로 끝낼. 해결 및 거부 기능을 새 약속에 전달하고 새 약속이 해결되거나 거부 될 때 해당 약속이 해결되거나 거부되는지 확인해야합니다.

이 사건의 경우는 performEdits 반복 (33) 거부를 처리하지 않습니다 또한 낭비이기 때문에이

function doEdits(previousPromise) { 
    someDB.performEdits() 
    .then((count) => { 
    if(count > 0) { 
     doEdits(this); 
    } else { 
     resolve(); 
    } 
    }) 
}; 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(() => { 
    someDB.performEdits() 
    .then((count) => { 
     if(count > 0) { 
     doEdits(this); 
     } else { 
     resolve(); 
     } 
    }) 
    }) 
}); 

를 수행하지 마십시오. 이론 상으로는 이것이 가능할 수도 있지만, 추론하는 것이 훨씬 더 어렵습니다.

관련 문제