2014-03-25 3 views
1

AFAIK Deferreds는 한 번만 해결할 수 있지만 테이블에 많은 Deferreds를 저장하는 시나리오가 있습니다. 이 지연 값을 으로 업데이트해야하지만은 다른 모듈이 지연된 원본에 대한 로컬 참조를 저장하기를 원하므로 새로운 객체로 전체 지연을 덮어 쓸 수는 없습니다.jquery.Delfer (또는 다른 약속)를 다시 해결

지연된 값을 덮어 쓸 수있는 방법이 있습니까? 아니면 의심스러운 (심지어 불가능할 수도 있습니다) 경우이 문제에 대한 시도 및 테스트 방법이 있습니까? 여기 오히려 당신이 JQuery와 Callbacks 객체를 저장하고 Ajax 호출이 완료 될 때를 게재 할 수있는 모듈 기사에 연기 저장하는 것보다 문제를

// articles module 
var articles = {}, 

// anId = 'uuid'; 

articles[anId] = $.get('/articles/' + anId); 

//another module 

var localCopyOfArticle, 
    getArticle = function (anId) { 
     localCopyOfArticle = articles[anId] 
    } 
getArticle('uuid'); 

// back to articles 
articles[anId] = $.get('/articles/refresh/' + anId); 

//another module again 
console.log(localCopyOfArticle) // oh no - it's out of date 

답변

2

AFAIK Deferreds 한 번만

올바른 해결할 수 있습니다. 보류 상태에서 이행 상태 또는 거절 상태로 전환 한 약속 (더 이상 해결되지 않음)은 더 이상 상태를 변경할 수 없습니다. 약속 사양이 명시 적으로 말한다 : 성취 할 때/거부, 약속 다른 상태로 전환하지 않아야합니다

.

그래서, 당신은 그것을 가지고 있습니다. 약속은 해결 된 후에 상태를 변경하지 않습니다. 값을 반환 한 함수가 갑자기 예외를 반환하지 않는 것처럼. 당신이 확실 할 때마다 - 당신이 약속이 후 거부 기대하지 않을 것이다처럼 던진 후에 당신은 그것을 반환 후 던지거나 돌아 foo을 기대하지 않을 것이다 동기 코드 비유

var x = foo(); // returns correctly 
// .. more code 

생각 거부 한 후 해결하거나 해결합니다.


(I 용의자로) 난의 지연 값 또는 경우를 덮어 쓸 수있는 몇 가지 방법이 권할 (불가능할)의이 문제에 대한 시도 및 테스트 방법이있다가 있습니까? 여기에 문제

없음을 설명하기 위해 몇 가지 골격 코드이다, 약속은 하나의 계산 통해 abstration입니다. 두 번 정착하는 것은 말이되지 않습니다. 그것은 당신의 목표에 대한 잘못된 추상 것처럼 보인다.

약속은 훌륭한 흐름 제어 메커니즘이지만 asnychronosu 코드가 처리해야하는 모든 문제를 해결하기위한 것이 아닙니다. 그것들은 이벤트 발생기가 아닙니다.

이 문제는 그러나 오히려 쉽게 약속 해결할 수 있습니다

// articles module 
var articles = {}, 

// anId = 'uuid'; 

articles.get = function(anId){ 
    if(articles[anId]){ 
     return $.when(articles[anId]); // return cached copy 
    } 
    return $.get('/articles/' + anId).then(function(article){ 
     articles[anId] = article; 
     return article; 
    }); 
} 
articles.refresh = function(anId){ 
    return $.get('/articles/refresh/' + anId).then(function(article){ 
      articles[anId] = article; 
      return article; 
    }); 
}); 

//another module 

var localCopyOfArticle, 
    getArticle = function (anId) { 
     return localCopyOfArticle = articles.get(anId); // now a promise 
    } 


// back to articles 
// the .then here is __CRUCIAL__ since the refresh operation is async itself 
articles.refresh(anId).then(function(article){ 
    console.log(article); // fresh 
    return getArticle(anId) 
}).then(function(article){ 
    console.log(article); // from getArticle, also fresh! 
}); 

이 코드는 점을 설명하기 위해 'cruft에'많이있다. 중요한 것은 작업이 매번 새로운 작업임을 깨닫는 것입니다. 데이터를 가져 오는 것은 매번 새로운 작업이며 동일한 작업이 아닙니다. 동기 코드처럼.약속이 아닌지도에 값을 저장하면 가져 오기 작업이 약속 기반이어야합니다.

+0

우수 답변 - 많은 감사 – wheresrhys

0

을 설명하기 위해 몇 가지 골격 코드입니다. 이것은 여러 가입자가 있고 각 가입자에게 여러 번 통지 할 수 있도록 할 수 있습니다 :

// articles module 
var articles = {}, 

// anId = 'uuid'; 

// create jquery callbacks object. 
articles[anId] = $.Callbacks(); 

// load the article and fire all callbacks that have been added to articles[anId] 
$.get('/articles/' + anId) 
    .then(function (data) { articles[anId].fire(data); }); 

// add a callback to articles[anId] whose purpose is to keep localCopyOfArticle up to date. 
var localCopyOfArticle = null; 
articles[anId].add(function(data) { 
    localCopyOfArticle = data; 
}); 

// back to articles 
articles[anId] = $.get('/articles/refresh/' + anId) 
    .then(function (data) { articles[anId].fire(data); }); 
관련 문제