2014-11-02 91 views
2

我剛剛開始在JavaScript中使用承諾,我想知道是否有一種方法來減少每個then回調函數中的封裝樣板代碼?我覺得自己這樣做了很多,不知道是否有更好的方法鏈接承諾與多個參數

例如,在我的下方getSettings功能無論是從數據庫(then)或默認設置模型(catch)返回設置模式。

var getSettings = function(instance, id, mode) { 
    return findByInstance(instance) 
     .then(function(data) { 
      return useModelFromData(data, id, mode); 
     }) 
     .catch(function() { 
      return useDefaultModel(id, mode) 
     }); 
}; 

var useModelFromData = function(data, id, mode) { 
    var settings = data.model.settings; 
    applyFeatures(settings, id, mode); 
    return data.model; 
}; 

var useDefaultModel = function(id, mode) { 
    var model = myModel.getDefaultModel(); 
    applyFeatures(model.settings, id, mode); 
    return model; 
}; 

我知道,如果當時的回調需要一個參數,並返回你可以做下面的快捷鍵的值:

get('some_url').then(JSON.parse).then(function(response) { 
    console.log("response", response); 
}); 

有沒有什麼捷徑,我可以爲多個參數呢?

+0

傳播如果你返回一個參數數組 - 看看傳播的藍鳥api:https://github.com/petkaantonov/bluebird/blob/master/API.md#spreadfunction-fulfilledhandler--function-rejectedhandler-- --promise – 2014-11-02 01:41:00

回答

6

使用bind和移動參數列表周圍

var getSettings = function(instance, id, mode) { 
    return findByInstance(instance) 
     .then(useModelFromData.bind(null, id, mode)) 
     .catch(useDefaultModel.bind(null, id, mode)); 
}; 

var useModelFromData = function(id, mode, data) { 
    var settings = data.model.settings; 
    applyFeatures(settings, id, mode); 
    return data.model; 
}; 

var useDefaultModel = function(id, mode) { 
    var model = myModel.getDefaultModel(); 
    applyFeatures(model.settings, id, mode); 
    return model; 
}; 

使用綁定您可以設置參數在執行功能時要預先考慮到的參數列表。因此,在這種情況下idmode將得到加在多數獲得通過,以useModelFromDatauseDefaultModel

+0

這是一個好主意,但只有在這種情況下,因爲id和mode已經在範圍內纔有效。如果findByInstance返回了三個其他變量,則必須找到另一種方式。這是op發佈的代碼片段的絕佳解決方案。 – 2014-11-02 01:50:01

+0

@rquinn:Promise只能將一個變量傳遞到下一個函數,儘管人們經常使用數組來解決這個問題。 – 2014-11-02 03:23:54

+0

不錯的一個!對我來說很完美。謝謝 – Decrypter 2014-11-02 05:29:23

0

的論點我通過這次走到今天,這就是我想出了....

function p(func){ 
    var args=[]; 
    for(var i=1,end=arguments.length;i<end;i++)args.push(arguments[i]); 
    return function(response){ 
    for(var i=0,end=args.length;i<end;i++){ 
     if(args[i]=='{response}')args[i]=response; 
    } 
    return func.apply(func,args); 
    } 
} 

以P你不會有需要改變你的電話,你可能只是做了函數的參數....

var getSettings = function(instance, id, mode) { 
    return findByInstance(instance) 
     .then(p(useModelFromData, '{response}', id, mode)) 
     .catch(p(useDefaultModel, id, mode)); 
}; 

繼承人我與它來了網頁...
http://plnkr.co/edit/4EGDTk?p=preview
...您可能會發現其他功能很有用。