2015-08-21 42 views
2

我有一些通過快速路徑獲取數據的代碼,並且如果快速路徑不可用,我想實現回退到慢速路徑。在這裏對node.js仍然非常新,所以我不知道如何去做這件事。我應該如何在節點中做到這一點?快速路徑和慢路徑

這裏是我的意思一個簡單的例子:

function getThing(callback) { 
    var thang = getThingTheFastWay(); 
    if (!thang) { 
     thang = getThingTheSlowWay(); 
    } 
    if (!thang || !thang.validate()) { 
     return callback(new Error('invalid thang')); 
    } 
    callback(null, thang); 
} 

所以在這裏我的目標是做I/O在getThingTheSlowWay()異步。該方法的後半部分是否需要爲getThingTheSlowWay()提供回調?

+0

如何確定快速路徑是否可用?由於node.js是異步的,所以'thang'可能總是未定義,具體取決於getThingTheFastWay()執行的時間。 –

回答

1

該方法的後半部分是否需要提供給getThingTheSlowWay()的回調?

是的,正好。對於異步結果,您無法執行thang =。你的函數將基本上是這樣的:

function getThing(callback) { 
    var thang = getThingTheFastWay(); 
    if (thang) { 
     if (!thang.validate()) 
      callback(new Error('invalid thang')); 
     else 
      callback(null, thang); 
    } else { 
     getThingTheSlowWay(function(err, thang) { 
      if (!err && !thang.validate()) 
       callback(new Error('invalid thang')); 
      else 
       callback(err, thang); 
     }); 
    } 
} 

爲了避免重複,你會使用命名函數:

function getThing(callback) { 
    function validateThang(err, thang) { 
     if (!err && !thang.validate()) 
      callback(new Error('invalid thang')); 
     else 
      callback(err, thang); 
    } 
    var thang = getThingTheFastWay(); 
    if (thang) 
     validateThang(null, thang); 
    else 
     getThingTheSlowWay(validateThang); 
} 

另一種方法是使用的承諾。假設getThingTheSlowWay返回一個承諾,而getThingTheFastWay沒有,它看起來像

function getThing() { 
    return Promise.resolve(getThingTheFastWay() || getThingTheSlowWay()) 
    .then(function validateThang(thang) { 
     if (thang.validate()) 
      return thang; 
     else 
      throw new Error('invalid thang'); 
    }); 
} 
+0

非常接近我結束了,非常感謝每個人。承諾和回調,哦,我的! –

+0

哦,我甚至沒有提到承諾解決方案:-) – Bergi

0

考慮使用的承諾。 https://www.promisejs.org/承諾允許您執行一些操作,並在完成時執行回調。如果快速操作失敗,則可以用慢動作恢復。所有這些行爲都可以與承諾一起工作。

需要考慮的一件事是,考慮到快速操作通常阻塞,慢操作可能不會很慢。遇到很多請求時可能會出現問題。

如果您不想使用承諾,請檢查快速版本是否正常工作並立即執行回調並返回。如果它沒有返回,您可能需要將回調傳遞到獲取慢速方式功能,因爲這將有一個回調調用回調參數的異步調用

1

我建議您始終使用回調,無論是否是「快」或不是。僅僅因爲你認爲速度很快,並不意味着它會一直存在 - 而且在高性能服務器領域,爲什麼寫一些可能會阻塞的東西呢?

function getThing(callback) { 
    var thang = getThingTheFastWay(function(err, thang) { 
     if (thang && !err) { 
      callback(err, thang); 
     } else { 
      getThingTheSlowWay(function(err, thang) { 
       callback(err, thang); 
      }); 
     } 
    }); 
} 

這當然需要重寫下游函數以支持回調,但是值得做。即使您使用第三方功能來執行此操作,將自己的回調包裝在長時間運行的功能上也非常簡單。

0

承諾可能是有用的位置:

function getThing() { 
    return new Promise(function(resolve, reject) { 
     getThingTheFastWay().then(function(result) { 
      resolve(result); 
     }).catch(function() { 
      getThingTheSlowWay().then(function(result) { 
       resolve(result); 
      }).catch(function() { 
       reject(); 
      }); 
     }); 
    }); 
} 

要使用這將是:

getThing().then(function(result) { 
    // do something with the result 
}); 

可以實現與和諧標誌的承諾,或者使用類似bluebird(推薦)

+2

避免[承諾構造函數反模式](http://stackoverflow.com/q/23803743/1048572)! – Bergi

+0

@Bergi相關:http://stackoverflow.com/questions/32214322/how-do-you-avoid-the-promise-constructor-antipattern-with-promise-all – Petah