【滲透】node.js經典問題

1.循環問題

當循環調用 require() 時,一個模塊可能在未完成執行時被返回。
例如如下狀況:
a.js:node

exports.done = false;
const b = require('./b.js');
console.log('在 a 中,b.done = %j', b.done);
exports.done = true;
console.log('a 結束');

b.js:app

console.log('b 開始');
exports.done = false;
const a = require('./a.js');
console.log('在 b 中,a.done = %j', a.done);
exports.done = true;
console.log('b 結束');

main.js:函數

console.log('main 開始');
const a = require('./a.js');
const b = require('./b.js');
console.log('在 main 中,a.done=%j,b.done=%j', a.done, b.done);

當 main.js 加載 a.js 時,a.js 又加載 b.js。 此時,b.js 會嘗試去加載 a.js。 爲了防止無限的循環,會返回一個 a.js 的 exports 對象的 未完成的副本 給 b.js 模塊。 而後 b.js 完成加載,並將 exports 對象提供給 a.js 模塊。
當 main.js 加載這兩個模塊時,它們都已經完成加載。 所以,該程序的輸出會是:
$ node main.jsui

main 開始
a 開始
b 開始
在 b 中,a.done = false
b 結束
在 a 中,b.done = true
a 結束
在 main 中,a.done=true,b.done=true

須要仔細的規劃, 以容許循環模塊依賴在應用程序內正常工做.this

2.原型繼承問題

須要注意的是call、apply、bind方法都只能繼承對象的方法,卻不能對它們的原型進行拷貝或繼承,爲此咱們通常使用混合的寫法,使用原型鏈和(apply或者call)方法進行繼承。
而在nodeJS中,util包提供了一個方法util.inherits(constructor, superConstructor)
因此就得以下,經過結合使用call和inherits才能將其徹底拷貝:prototype

function Girl(name){
    this.name = name;
    EventEmitter.call(this);
}
util.inherits(Girl,EventEmitter);

var girl = new Girl();
注意,不建議使用 util.inherits()。 請使用 ES6 的 class 和 extends 關鍵詞得到語言層面的繼承支持。 注意,這兩種方式是語義上不兼容的。

constructor <Function>
superConstructor <Function>
從一個構造函數中繼承原型方法到另外一個。 constructor 的原型會被設置到一個從 superConstructor 建立的新對象上。code


superConstructor 可經過 constructor.super_ 屬性訪問。對象

const util = require('util');
const EventEmitter = require('events');

function MyStream() {
  EventEmitter.call(this);
}

util.inherits(MyStream, EventEmitter);

MyStream.prototype.write = function(data) {
  this.emit('data', data);
};

const stream = new MyStream();

console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true

stream.on('data', (data) => {
  console.log(`接收的數據:"${data}"`);
});
stream.write('運做良好!'); // 接收的數據:"運做良好!"

例子:使用 ES6 的 class 和 extends:繼承

const EventEmitter = require('events');

class MyStream extends EventEmitter {
  write(data) {
    this.emit('data', data);
  }
}

const stream = new MyStream();

stream.on('data', (data) => {
  console.log(`接收的數據:"${data}"`);
});
stream.write('使用 ES6');
相關文章
相關標籤/搜索