2013-07-07 36 views
25

鏈接用是有沒有辦法鏈Promises在一起的CoffeeScript。例如,考慮下面的JavaScript代碼,在CoffeeScript中

then's
return $.getJSON('/api/post.json') 
    .then(function(response) { 
    // do something 
    }) 
    .then(function(response) { 
    // do something 
    }) 
    .then(null, function(err) { 
    // do something 
    }); 

每個是可選的,並且需要最終then由函數返回。 目前,我在CoffeeScript中爲寫這個,

promise = $.getJSON('/api/post.json') 
promise = promise.then (response) -> 
    // do something 

promise = promise.then (response) -> 
    // do something 

promise = promise.then null, (err) -> 
    // do something 

return promise 

有沒有更好的方式來做到這一點?謝謝。

+0

你也可以看看IcedCoffeeScript。它的工作方式有點不同,但工作得很好。 – 2013-07-07 17:18:17

回答

40

以西結書顯示了正確的方式,但它並不需要周圍的功能括號。只是做:

$.getJSON '/api/post.json' # As of CoffeeScript 1.7, you don't need the parentheses here either. 
.then (response) -> 
    # do something 
    response # if you would not return anything, promise would be fulfilled with undefined 
.then (response) -> 
    # do something 
    undefined # necessary to prevent empty function body 
.then null, (err) -> 
    # handle error 

我認爲這是令人驚訝的乾淨。 的一件事是比較混亂的是,當你需要同時添加onRejected和onFulfilled處理程序。

注:我最後一次檢查,這並沒有在CoffeeScript中Redux的工作,但是這是在幾個月前。

注2:你需要爲這個在每個函數體實際的代碼(即不只是一個評論)至少一條線的工作。通常情況下,你會的,所以這不是一個大問題。

+0

謝謝。這適用於Coffeescript編譯器。 –

+0

因爲在CoffeeScript 1.4.0或1.6.3(最新版本)中無法編譯,因此需要降級。我的答案中顯示的括號是必需的。 –

+4

@EzekielVictor:感謝提高警惕。我只是看着它,問題似乎是鏈條的第二部分缺乏一個功能主體。縮進評論似乎不夠。我在末尾添加了一個明確的「undefined」,以便編譯。我從來沒有遇到過這個問題,因爲我從來沒有在這些地方有非空的函數體。 –

4

這可能是你做的最好的:

$.getJSON('/api/post.json') 
    .then((response) -> 
     # do something 
    ).then((response) -> 
     # do something 
    ).then null, (err) -> 
     # do something 

注意周圍的then()參數的括號內。沒有什麼可怕的,但希望這有助於。

+0

謝謝。正如@Meryn Stol所建議的,放棄括號使得它更好一點。 –

+3

鬆開括號?我認爲你的意思是失去他們。放棄對這個世界的括號的想法確實令人恐懼。 –

12

這是我寫的承諾,帶着一點點額外的壓痕

doSomething =() -> new RSVP.Promise (resolve, reject) -> 
    if 1 is 1 
    resolve 'Success' 
    else 
    reject 'Error' 

doSomething() 
.then (res) -> 
     console.log 'Step 1 Success Handler' 

    , (err) -> 
     console.log 'Step 1 Error Handler' 

.then (res) -> 
     console.log 'Step 2 Success Handler' 

.then (res) -> 
     console.log 'Step 3 Success Handler' 

    , (err) -> 
     console.log 'Step 3 Error Handler' 

哪個編譯個人最喜歡的方式:

var doSomething; 

doSomething = function() { 
    return new RSVP.Promise(function(resolve, reject) { 
    if (1 === 1) { 
     return resolve('Success'); 
    } else { 
     return reject('Error'); 
    } 
    }); 
}; 

doSomething().then(function(res) { 
    return console.log('Step 1 Success Handler'); 
}, function(err) { 
    return console.log('Step 1 Error Handler'); 
}).then(function(res) { 
    return console.log('Step 2 Success Handler'); 
}).then(function(res) { 
    return console.log('Step 3 Success Handler'); 
}, function(err) { 
    return console.log('Step 3 Error Handler'); 
}); 

有有些情況下這個作品真的很好過:

step1Success = (res) -> console.log 'Step 1 Success Handler' 
step1Error = (err) -> console.log 'Step 1 Error Handler' 

step2Success = (res) -> console.log 'Step 2 Success Handler' 

step3Success = (res) -> console.log 'Step 3 Success Handler' 
step3Error = (err) -> console.log 'Step 3 Error Handler' 

doSomething() 
    .then(step1Success, step1Error) 
    .then(step2Success) 
    .then(step3Success, step3Error) 

測試咖啡腳本v1.6.3

+0

這個效果很好,唯一讓我想起來的事情是確保你在代碼中沒有任何空格。這對於那些新的coffeescript來說可能很常見,但是我不能得到類似上面的代碼,直到我意識到我在一組製表符中有一個空格。 –