2014-03-01 121 views
0

下面的代碼返回每個的getJSON方法的RSVP承諾:廢渣處理的承諾

getJSON('/login') 
    .then(getJSON('/errors').then(function(users) { 
    self.user = users; 
    })) 
    .then(getJSON('contacts').then(function(contacts) { 
    self.contacts = contacts; 
    })) 
    .then(getJSON('companies').then(function(companies) { 
    self.companies = companies; 
    callback(self); 
    }, function(err){ 
    console.log('does not get here') 
    })); 

我承諾的理解顯然是錯誤的,我不想爲每個錯誤回調然後,而是我認爲該錯誤將被轉發到下一個隨後的函數之一中的下一個可用的錯誤回調。

在上面的代碼中,第2行上的getJSON將被拒絕,但它不會被轉發到最後一次的錯誤回調。

我必須爲每個提供一個錯誤回調。這與回調地獄沒有任何區別。

回答

2

我認爲你是以錯誤的方式鎖定你的承諾。在上一次完成後,您的getJSONS不會連續執行。 當您調用第一個getJSON(getJSON('/ login'))時,您沒有將兩個處理程序傳遞給它的then方法。您正在傳遞一個新的getJSON調用。這意味着,在調用getJSON完成之後(但在ajax調用結束之前),您正在執行第二個getJSON(getJSON('/ errors'))。您將所得承諾作爲getJSON('/ login')的then方法的第一個參數傳遞。通過這樣做,這個承諾將解決或拒絕與getJSON('/ errors')相同的值。好吧,但...

.then(getJSON('companies').then(function(companies) { 
    self.companies = companies; 
    callback(self); 
    }, function(err){ 
    console.log('does not get here') 
    })); 

在這裏,你傳遞一個新的承諾,一個是的getJSON(公司)爲一則方法的第一個參數返回。這個方法所屬的承諾,當被拒絕時,會嘗試調用作爲第二個參數傳遞的函數......但是沒有!所以,因爲getJSON('公司')不拒絕,你不會收到錯誤。我已經重寫你的連鎖店:

getJSON('/login').then(
    function(users) { 
     self.user = users; 
     return getJSON('/errors'); 
    }).then(function() { 
     return getJSON('contacts') 
    }).then(function(contacts) { 
     self.contacts = contacts; 
     return getJSON('companies'); 
    }).then(function(companies) { 
     self.companies = companies; 
     callback(self); 
    }, function(err){ 
    console.log('does not get here') 
    }); 

現在我認爲它應該可以正常工作。在每個承諾的成功解決之後,執行一個新的getJSON請求的函數將會執行,並且它會返回它的承諾。如果他們中的任何一個拒絕,拒絕將通過,直到找到第二個參數,然後發生在鏈的末尾。最後一個函數(err)將捕獲在該點之前出錯的任何內容。

+0

+1這個答案看起來像是有正確的想法,請考慮澄清一下(目前這有點「文字牆」)。另外,我更喜歡'.catch'而不是',function(err){' –

+0

你是對的,但是這裏有點晚了。我會盡力解釋明天會更好。順便說一句,我不知道RVSP具體實現了promise/A +,所以我不知道它有一個特定的.catch()方法。 –

+1

儘管對於所有承諾/ A +實現並非如此,事實上絕大多數承諾庫(以及DOM期貨和原生ES6承諾)都有一個'.catch'方法。 [Q](http://goo.gl/FkIfne),[$ q](http://goo.gl/qF6M4q),[RSVP](http://goo.gl/0310T1),[藍鳥]( http://goo.gl/rTpHxX),[when](http://goo.gl/2VZduJ)和[native](http://goo.gl/FtXLM4)都可以。 –

3

你有沒有任何理由一次不提出所有請求?

self.user = getJSON("login"); 
self.contacts = getJSON("contacts"); 
self.companies = getJSON("companies"); 
// not sure what "/errors" does or what you assign it to, add it if you please 

//.hash will go through object properties and wait for all promises to resolve 
return RSVP.hash(self).then(function(results){ 
    //here, self now contains .user .contacts and .companies 
    callback(self); //DO NOT do this, instead return the promise 
}).catch(function(err){ 
    //this is where all error handling goes 
}); 

注意return那裏,這是最好的回報諾言,而不是調用回調函數,你可以從外部.then它。

2

與Benjamin Gruenbaum相似,但稍微簡潔一些。

return RSVP.hash({ 
    user: getJSON("login"); 
    contacts: getJSON("contacts"); 
    companies: getJSON("companies"); 
}}).then(callback).catch(function(err){ 
    //this is where all error handling goes 
});