真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

nodejs中如何實現(xiàn)事件循環(huán)

nodejs中如何實現(xiàn)事件循環(huán),很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司堅信:善待客戶,將會成為終身客戶。我們能堅持多年,是因為我們一直可值得信賴。我們從不忽悠初訪客戶,我們用心做好本職工作,不忘初心,方得始終。10余年網(wǎng)站建設經(jīng)驗成都創(chuàng)新互聯(lián)公司是成都老牌網(wǎng)站營銷服務商,為您提供網(wǎng)站建設、網(wǎng)站制作、網(wǎng)站設計、H5網(wǎng)站設計、網(wǎng)站制作、高端網(wǎng)站設計、成都微信小程序服務,給眾多知名企業(yè)提供過好品質(zhì)的建站服務。

process.nextTick
  • process.nextTick()不在event loop的任何階段執(zhí)行,而是在各個階段切換的中間執(zhí)行;即從一個階段切換到下個階段前執(zhí)行;

  • 三種定義異步事件的方式: setTimeout,setImmediate,process.nextTick()

var fs = require('fs');
fs.readFile(__dirname,() =>{
    setTimeout(() =>{
        console.log('setTimeout')
    })
    
    setImmediate(() =>{
        console.log('setImmediate')
        process.nextTick(() =>{
            console.log('nextTick3')
        })
    })
    
    process.nextTick(() =>{
            console.log('nextTick1')
    })
    
    process.nextTick(() =>{
            console.log('nextTick2')
    })
})
// nextTick1 nextTick2 setImmediate nextTick3 setTimeout
nextTick應用場景
  1. 在多個事件交叉執(zhí)行cpu運算密集型的任務

var http = require('http');
function compute(){
    process.nextTick(compute)
}
http.createServer(function(req,res){
// 服務請求的時候,還能抽空進行一些計算任務;
    res.writeHead(200, {'Content-type': 'text/plain'})
    res.end('hello world');
})
compute()
  • 在這種模式下,我們不需要遞歸的調(diào)用compute(),我們只需要在事件循環(huán)中使用process.nextTict()定義;compute()在下一個事件點執(zhí)行即可;在這個過程中,如果有新的http請求進來,事件循環(huán)機制會先處理新的請求,然后再調(diào)用copute().反之,如果把compute()放在一個遞歸里調(diào)用,那系統(tǒng)一直會阻塞在compute()里,無法處理新的http請求了。

  1. 保持回調(diào)函數(shù)異步執(zhí)行的原則

  • 當給一個函數(shù)定義一個回調(diào)函數(shù)時,要確保這個回調(diào)是異步執(zhí)行的(定義一個callback,但是又需要在callback里面使用這個變量);

  • 下面示例違反了這一原則:

function asyncFake(data,callback){ // 同步執(zhí)行
    if(data === 'foo') callback(true)
    else callback(false)
}
asyncFake('bar',function(result){
    // this callback is actually called synchronously!
})

為什么這樣不好呢?看下面nodejs文檔里的一段代碼

var client = net.connect(8124, function(){
    console.log('client connect');
    client.write('world'); // 會報錯
})

在上面的代碼里,如果因為某種原因,net.connect()變成同步執(zhí)行的了,回調(diào)函數(shù)就會立刻被執(zhí)行,因此回調(diào)函數(shù)寫到客戶端的變量就用于不會被初始化了; 這種情況下我們就可以用process.nextTick()把上面的asyncFake改成異步執(zhí)行的;

function asyncReal(data, callback){
    process.nextTick(function(){
        callback(data === 'foo')
    })
}
  1. 用在事件觸發(fā)過程中

EventEmitter 有兩個比較核心的方法,on和Emit。node自帶的發(fā)布/訂閱模式;

var EventEmitter = require('events').EventEmmiter;
function StreamLibrary(resourceName){
    this.emit('start')
}
StreamLibrary.prototype.__proto__ = EventEmitter.prototype; // inherit from EventEmitter
var stream = new StreamLibrary('fooResouce');

stream.on('start', function(){
    console.log('Reading has started')
})

以上代碼在new StreamLibrary的時候,已經(jīng)觸發(fā)了emit,此時 還沒有訂閱,console.log不會執(zhí)行 解決方案如下:用異步方法包裝

function StreamLibrary(resource){
    var self = this;
    // 保證訂閱在發(fā)布之前
    process.nextTick(function(){ 
        self.emit('start');
    })
// read from the file,and for every chunck read.do;
this.emit('data', chunkRead)
}

發(fā)布訂閱模式

const EventEmitter = require('events').EventEmitter;
class App extends EventEmmiter{
    
}
let app = new App();

app.on('start',() =>{ // 訂閱
    console.log('start');
})

app.emit('start') // emit 觸發(fā),emit是個同步的方法
console.log(111);  // 如果需要emit是異步的,可以通過三種異步方法去包裝
// start 111

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。


網(wǎng)頁名稱:nodejs中如何實現(xiàn)事件循環(huán)
分享地址:http://weahome.cn/article/gggeph.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部