本文介紹了Node異步編程,分享給大家,具體如下:
目前的異步編程主要解決方案有:
事件發布/訂閱模式 Promise/Deferred模式 流程控制庫事件發布/訂閱模式
Node自身提供了events模塊,可以輕松實現事件的發布/訂閱
//訂閱emmiter.on("event1",function(message){ console.log(message);})//發布emmiter.emit("event1","I am mesaage!");偵聽器可以很靈活地添加和刪除,使得事件和具體處理邏輯之間可以很輕松的關聯和解耦
事件發布/訂閱模式常常用來解耦業務邏輯,事件發布者無需關注訂閱的偵聽器如何實現業務邏輯,甚至不用關注有多少個偵聽器存在,數據通過消息的方式可以很靈活的進行傳遞。
下面的HTTP就是典型的應用場景
var req = http.request(options,function(res){ res.on('data',function(chunk){ console.log('Body:'+ chunk); }) res.on('end',function(){ //TODO })})如果一個事件添加了超過10個偵聽器,將會得到一條警告,可以通過調用emmite.setMaxListeners(0)將這個限制去掉
繼承events模塊
var events = require('events');function Stream(){ events.EventEmiiter.call(this);}util.inherits(Stream,events.EventEmitter);利用事件隊列解決雪崩問題
所謂雪崩問題,就是在高訪問量,大并發量的情況下緩存失效的情況,此時大量的請求同時融入數據庫中,數據庫無法同時承受如此大的查詢請求,進而往前影響到網站整體的響應速度
解決方案:
var proxy = new events.EventEmitter();var status = "ready"; var seletc = function(callback){ proxy.once("selected",callback);//為每次請求訂閱這個查詢時間,推入事件回調函數隊列 if(status === 'ready'){ status = 'pending';//設置狀態為進行中以防止引起多次查詢操作 db.select("SQL",function(results){ proxy.emit("selected",results); //查詢操作完成后發布時間 status = 'ready';//重新定義為已準備狀態 }) }}多異步之間的協作方案
以上情況事件與偵聽器的關系都是一對多的,但在異步編程中,也會出現事件與偵聽器多對一的情況。
這里以渲染頁面所需要的模板讀取、數據讀取和本地化資源讀取為例簡要介紹一下
var count = 0 ;var results = {};var done = function(key,value){ result[key] = value; count++; if(count === 3){ render(results); }}fs.readFile(template_path,"utf8",function(err,template){ done('template',template)})db.query(sql,function(err,data){ done('data',data);})l10n.get(function(err,resources){ done('resources',resources)})偏函數方案
var after = function(times,callback){ var count = 0, result = {}; return function(key,value){ results[key] = value; count++; if(count === times){ callback(results); } }}var done = after(times,render);var emitter = new events.Emitter();emitter.on('done',done); //一個偵聽器emitter.on('done',other); //如果業務增長,可以完成多對多的方案fs.readFile(template_path,"utf8",function(err,template){ emitter.emit('done','template',template);})db.query(sql,function(err,data){ emitter.emit('done','data',data);})l10n.get(function(err,resources){ emitter.emit('done','resources',resources)})
新聞熱點
疑難解答
圖片精選