2017-03-16 1 views
1

을 약속 내 상황입니다 : 각각의 setTimeout 콜백 패턴을 사용하여 다른 비동기 작업입니다비동기 기능은 내부 여기

fetchData(foo).then(result => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      resolve(result + bar); 
     }, 0) 
    }); 
}).then(result => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      resolve(result + woo); 
     }, 0) 
    }); 
}).then(result => { 
    setTimeout(() => { 
     doSomething(result); 
    }, 0) 
}); 

.

fetchData(foo).then(result => { 
    setTimeout(() => { 
     return result + bar; 
    }, 0) 
}).then(result => { 
    setTimeout(() => { 
     return result + woo; 
    }, 0) 
}).then(result => { 
    setTimeout(() => { 
     doSomething(result); 
    }, 0) 
}); 

은 분명히이 작동하지 않습니다 코드가 더 같이해야 같은

약속 내부의 각 기능을 래핑하는 정말 고통 스럽다이다, 나는 생각합니다.

약속 사용 중입니까? 약속에있는 모든 기존 비동기 함수를 정말로 래핑해야합니까?

편집 :

이 사실 나는 내 예제에서의 setTimeout이 비동기 작업 도중 reprensent하기위한 것입니다 것을 분명히하지 않았다, 내 예를 들어 내 상황을 완전히 reprensentative 아니었다 알고 있습니다. 이 상황이 내 상황을 더 잘 나타내줍니다.

fetchData(foo).then(result => { 
    return new Promise((resolve, reject) => { 
     asyncOperation(result, operationResult => { 
      resolve(operationResult); 
     }, 0) 
    }); 
}).then(result => { 
    return new Promise((resolve, reject) => { 
     otherAsyncOperation(result, otherAsyncResult => { 
      resolve(otherAsyncResult); 
     }, 0) 
    }); 
}).then(result => { 
     doSomething(result); 
}); 
+0

약속을 사용하지 않으려면 맞춤 이벤트를 사용할 수 있습니다. 이 이벤트는 변경 사항을 감지 할 때마다 트리거됩니다! (https://www.sitepoint.com/javascript-custom-events/).하지만 왜 당신은 약속을 사용하는 것을 좋아하지 않습니까? –

+1

기존 콜백 기반 비동기 기능을 약속하는 데 도움이되는 ['pify'] (https://github.com/sindresorhus/pify)와 같은 모듈이 있습니다. 또한 합리적인 수의 패키지가 비동기 함수에 대한 약속과 콜백 지원을 제공합니다 (콜백 함수를 전달하지 않으면 약속을 반환합니다). 그러나 이것이 당신의 상황에 적용되는지는 말할 수 없습니다. – robertklep

+0

^^ 예 또는 'bluebird'는 매우 단순하며 기본 약속처럼 작동하지만 노드 스타일 콜백에 더 친숙합니다. [link] (http://bluebirdjs.com/docs/api/promise.fromcallback.html) – user3821538

답변

3
당신이 모든 시간을 setTimeout 포장 약속을 만들의 소음을 줄이려면

말했다 그래서, 당신은 유틸리티 기능 setTimeoutWithPromise를 만들 수 있습니다

약속 사용 중입니까? 약속에있는 모든 기존 비동기 함수를 정말로 래핑해야합니까?

예. 예. 코드가 더 아니, 안이

과 같아야 같은

는 느낌. 그것은 오히려 다음과 같아야합니다

function promiseOperation(result) { 
    return new Promise((resolve, reject) => { 
     asyncOperation(result, resolve, 0) 
    }); 
} 
function otherPromiseOperation(result) { 
    return new Promise((resolve, reject) => { 
     otherAsyncOperation(result, resolve, 0) 
    }); 
} 

fetchData(foo).then(promiseOperation).then(otherPromiseOperation).then(doSomething); 

약속

잘 내부에 각 기능을 래핑하는 정말 고통 스럽다이다,하지 반복해서 모든 시간을 쓰기. 이 래핑을 함수로 추상화 할 수 있습니다!

대부분의 약속 라이브러리에는 이러한 약속 기능이 포함되어 있으므로 전체 코드가이 세 줄로 줄어 듭니다.

0

약속의 권리를 사용하고 있습니다. 코드의 첫 번째 조각에 그냥 작은 참고 : fetchData의 발신자로 돌아 가지 않고 비동기 작업을 할 단순히해야하는 경우

... 
}).then(result => { 
    setTimeout(() => { 
     doSomething(result); 
    }, 0) 
}); 

이 올바른 : 당신은 마지막 then() 콜백에서 약속을 반환하지 않습니다 마지막 비동기 조작의 값. 이 값을 돌려 줄 필요가있는 경우, 당신도이 작업을 약속로 변환해야합니다

fetchData(foo).then(result => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      resolve(result + bar); 
     }, 0) 
    }); 
}).then(result => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      resolve(result + woo); 
     }, 0) 
    }); 
}).then(result => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      resolve(doSomething(result)); 
     }, 0) 
    }); 
}); 

가 여기에 내가 doSomething가 값을 반환하는 동기 기능입니다 가정합니다. 코드

function setTimeoutWithPromise(operation, millisec) { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
      resolve(operation()); 
     }, millisec) 
    }); 
} 

그리고 청소 :

fetchData(foo) 
    .then(result => setTimeoutWithPromise(() => result + bar, 0)) 
    .then(result => setTimeoutWithPromise(() => result + woo, 0)) 
    .then(result => setTimeoutWithPromise(() => doSomething(result), 0)); 
관련 문제