2016-06-27 3 views
1

사용 사례 - 여러 개의 URL을 가져 와서 결과를 캐싱합니다. 빠른 속도 (500ms)는이 패스에 통합되며, 그 시간보다 오래 걸리고 다음 번에 캐시에 저장되므로 (앱에서 ~ 10 분 후) 캐시에 저장됩니다.Promise.some()에 시간 초과가 있습니까?

Promise.someWithTimeout(promises, timeout)과 같은 결과를 얻고 싶습니다. 결과는 시간 초과가 만료되기 전에 완료된 해결 된 값의 배열입니다.

뭔가 약속의 각 보이는

Promise.someWithTimeout([promises], <timeout value>) 
.then((results) => { 
    //stuff 
}) 

같은 ( Promise.some()이 아닌 제한 시간이 수를 필요로 정말 가까운)

return memcache.getAsync(keyFromUrl(url)) 
.then((cacheRes) => { 
    if(cacheRes) return cacheRes; 
    //not in cache go get it 
    return rp(url) 
    .then((rpRes) => { 
    //Save to cache but don't wait for it to complete 
    memcache.setAsync(keyFromUrl(url), rpRes, 86400).catch((e) => { /*error logging*/ }) 
    return rpRes; 
    }) 
}) 

있는 아이디어 같은 URL이 돌아 오면 그 빨리 우리는 그것을 사용한다. 우리가 보석을 얻는데 더 오래 걸리더라도 다음 번에 결과를 캐쉬하면 우리는 그것을 가진다. 따라서 rp() 시간 초과는 Promise.someWithTimeout()보다 훨씬 길어집니다.

누구든지이 작업을 수행 할 수있는 lib를 작성 했습니까? 아니면 더 좋은 패턴이 있습니까? 나는 Promise.all().timeout().finally()을 사용하여 배열에 결과를 숨기 겠다는 약속을했지만, 내 손가락을 댈 수는 없다고 생각합니다.

+0

는 각 패스가 동일한 "URL을의 무리"를 구성 하는가 또는 통과하는 통과에 따라 다를 수 있습니까? –

답변

3

일회성 코딩를 들어, 두 개의 별도의 약속 체인을 시작하고 시간 초과가 이미 일어난 있는지 확인하기 위해 플래그를 사용할 수 있습니다 : 당신이 하나의 방법으로이 기능을 패키지하려면

var timedOut = false; 
// your regular code 
Promise.all(...).then(function() { 
    // cache the result, even if it came in after the timeout 

    if (!timedOut) { 
     // if we didn't time out, then show the response 
    } 
}); 

Promise.delay(1000).then(function() { 
    timedOut = true; 
    // do whatever you want to do on the timeout 
}); 

및 시간이 초과되었다는 사실과 시간 초과 후에도 최종 결과에 액세스 할 수 있으므로 (예를 들어 캐시 할 수 있으므로), 정보가 둘 이상인 내용으로 해결해야합니다 . 하나 이상의 정보를 포함 할 수있는 객체로 해결함으로써 시간 초과 및 최종 데이터에 대한 액세스를 허용하는 한 가지 방법이 있습니다.

Promise.someWithTimeout = function(promiseArray, cnt, timeout) { 
    var pSome = Promise.some(promiseArray, cnt).then(function(results) { 
     return {status: "done", results: results}; 
    }); 
    var pTimer = Promise.delay(cnt).then(function() { 
     return {status: "timeout", promise: pSome} 
    }); 
    return Promise.race([pSome, pTimer]); 
} 

// sample usage 
Promise.someWithTimeout(arrayOfPromises, 3, 1000).then(function(result) { 
    if (result.status === "timeout") { 
     // we timed out 
     // the result of the data is still coming when result.promise is resolved if you still want access to it later 
     result.promise.then(function(results) { 
      // can still get access to the eventual results here 
      // even though there was a timeout before they arrived 
     }).catch(...); 
    } else { 
     // result.results is the array of results from Promise.some() 
    } 
}); 

+0

@JohnPetitt - 여기 옵션에 대해 어떻게 생각하세요? 이 질문에 대답하거나 유용한 옵션을 제공합니까? – jfriend00

+0

그래, 그게 의미가있어, 이제는 약속 된 약속이 모든 약속을 배열에 넣은 다음 계속 Promise.all (약속).) 자신과 Promise.delay (500) .then (() => Promise.some (array) 반환)에서 실행되도록 남겨두고 결과를 사용하면 최적의 솔루션이됩니다. –

+0

귀하의 제안은 응답이 그보다 빨리 되더라도 500ms의 지연을 강요합니다. 나는 Promise.all()이 캐시에서 저장하기 위해 자체적으로 실행되도록 남겨둔다는 것에 동의한다. 그런 다음 시간 제한을 위해 타이머와 함께 동일한 약속을 사용하십시오. – jfriend00

관련 문제