2014-05-06 57 views
0

我是新來的when.js JavaScript庫,但我熟悉C#中的異步編程。這就是爲什麼我覺得這個代碼是笨重:我可以解開'何時'承諾調用的嵌套嗎?

filters.doFilter('filter1name', reqAndPosts).then(function(filter1) { 
    filters.doFilter('filter2name', filter1).then(function(filter2) { 
     filters.doFilter('filter3name', filter2).then(function (posts) { 
      renderView(posts); 
     }); 
    }); 
    return filter1; 
}); 

我基本上要被按順序調用三種方法,與每個被輸送到下一個方法的輸出。無論如何,我可以將此代碼重構爲更「序列化」 - 即擺脫嵌套?我覺得在這裏我錯過了when框架。我做得不對,對吧?

+0

可能重複的[不承諾只是回調?](http://stackoverflow.com/questions/22539815/arent-promises-just-callbacks) –

回答

3

由於doFilter返回一個承諾,我們可以做

filters.doFilter('filter1name', reqAndPosts) 
    .then(function(filter1) { 
     return filters.doFilter('filter2name', filter1); 
    }) 
    .then(function(filter2) { 
     return filters.doFilter('filter3name', filter2); 
    }) 
    .then(renderView); 
+1

Nilzor,而你現在的方法會使以前的結果操作可在所有後續操作(範圍)中使用,@thefourtheye方法可使結果更清晰並更易於閱讀代碼。兩者都有不同的適合場景。 –

+0

是的。更清潔的代碼是我現在正在尋找的,所以就是這樣。謝謝。 – Nilzor

+0

@AkashAgrawal不,因爲我的回答顯示,有更好的方法:) –

3

還有另一種選擇有可用的清潔壓痕和以前的結果兩者的優點:使用withThis

filters.doFilter('filter1name', reqAndPosts).withThis({}).then(function(filter1) { 
    this.filter1 = filter1; // since we used withThis, you use `this` to store values 
    return filters.doFilter('filter2name', filter1); 
}).then(function(filter2) { 
    // use "this.filter1" if you want 
    return filters.doFilter('filter3name', filter2); 
}).then(renderView); 
+0

When.js現在已經綁定過 – Esailija

+0

@Esailija感謝,編輯 –

+0

https://github.com/cujojs/when/blob/master/docs/api.md#promisewith – Esailija

1

只要有一點想法,你可以寫,將採取起始對象和過濾器序列作爲其參數的廣義效用函數,動態地構建所需的.then鏈,並返回多過濾結果的承諾。

功能將這個樣子......

function doFilters(filterArray, startObj) { 
    return filterArray.reduce(function(promise, f) { 
     return promise.then(function(result) { 
      return filters.doFilter(f, result); 
     }); 
    }, when(startObj)); 
} 

...這是在標題爲「收集亂哄哄」一節中給出here模式的適應。

對於要操作,調用如下:

doFilters(['filter1name', 'filter2name', 'filter3name'], reqAndPosts).then(function(result) { 
    //All filtering is complete. 
    //Do awesome stuff with the result. 
}); 

Provding它不被破壞的範圍是,doFilters()將仍然可以在代碼中的其他地方使用:

doFilters(['f1', 'f2', 'f3'], myOtherObject).then(function(result) { 
    //... 
}); 

只需花費很少的努力,您可以通過doFilters()作爲filters的方法來整理。這將是最好的。

+0

尼斯。這或多或少是'when.pipeline()'做的,對吧?我開始獲得在Javascript承諾一抓,你的崗位在這方面一定幫助。 https://github.com/cujojs/when/blob/master/docs/api.md#whenpipeline – Nilzor

+0

Nilzor,我不是一個真正的'when'人 - 我的大部分承諾的經驗在於jQuery的 - 但是從我理解'when'提供三種相關的方法'when.reduce','when/sequence'和'when/pipeline'作爲「處理異步承諾和任務數組的好方法」。沒有通過文檔拖網',我不確定哪個是最相關的,但是可能是'when/pipeline'。我用JS的本地'array.reduce()',其迅速成爲優選的方法。使用