Nodejs Guides(四)
EVENTS
events模块API实例
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { } //EventListener 会按照监听器注册的顺序同步地调用所有监听器。 //所以需要确保事件的正确排序且避免竞争条件或逻辑错误。 //监听器函数可以使用 setImmediate() 或 process.nextTick() 方法切换到异步操作模式: const myEmitter = new MyEmitter(); myEmitter.on('event', (a, b) => { setImmediate(() => { console.log('这个是异步发生的'); }); }); myEmitter.on('event1', () => { console.log('触发了一个事件1!'); }); myEmitter.on('event2', () => { console.log('触发了一个事件2!'); }); //eventEmitter.once() 方法时可以注册一个对于特定事件最多被调用一次的监听器。 当事件被触发时,监听器会被注销,然后再调用。 let m = 0; myEmitter.once('event3', () => { console.log(++m); }); //当EventEmitter 实例中发生错误时,会触发一个 'error' 事件。 这在 Node.js 中是特殊情况。 //最佳实践,应该始终为 'error' 事件注册监听器。 myEmitter.on('error', (err) => { console.error('有错误'); }); //emitter.prependListener() 方法可用于将事件监听器添加到监听器数组的开头。 myEmitter.prependListener('event', () => console.log('b')); //添加一个单次 listener 函数到名为 eventName 的事件的监听器数组的开头。 下次触发 eventName 事件时,监听器会被移除,然后调用。 myEmitter.prependOnceListener('event', (stream) => { console.log('c'); }); myEmitter.emit('error', new Error('whoops!')); myEmitter.emit('event3'); myEmitter.emit('event3'); myEmitter.emit('event'); myEmitter.emit('event2'); myEmitter.emit('event1'); myEmitter.emit('event');
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); //this指向MyEmitter // myEmitter.on('event', function (a, b) { // console.log(a, b, this); // }); //this指向空对象 myEmitter.on('event', (a, b) => { console.log(a, b, this); // 打印: a b {} }); myEmitter.emit('event', 'a', 'b');
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); // 当EventListener 所注册的事件发生的时候,该方法会被调用 myEmitter.once('newListener', (event, listener) => { if (event === 'event') { // 在开头插入一个新的监听器 myEmitter.on('event', () => { console.log('B'); }); } }); myEmitter.on('event', () => { console.log('A'); }); myEmitter.emit('event'); myEmitter.emit('event');
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { } const myEmitter = new MyEmitter(); // 在事件触发后、最后一个监听器完成执行后,从名为 eventName 的事件的监听器数组中移除指定的 listener。 const callbackA = () => { console.log('A'); myEmitter.removeListener('event', callbackB); }; const callbackB = () => { console.log('B'); }; myEmitter.on('event', callbackA); myEmitter.on('event', callbackB); myEmitter.emit('event'); myEmitter.emit('event');
URL
WHATWG URL API实例
const {URL} = require('url'); const myURL1 = new URL('https://abc:xyz@example.com'); console.log(myURL1); const myURL2 = new URL('/foo', 'https://example.org/'); console.log(myURL2); const myURL3 = new URL('https://example.org/abc?asd=abc'); console.log(myURL3.searchParams); const myURLs = [ new URL('https://www.example.com'), new URL('https://test.example.org') ]; console.log(JSON.stringify(myURLs)); // ┌─────────────────────────────────────────────────────────────────────────────────────────────┐ // │ href │ // ├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤ // │ protocol │ │ auth │ host │ path │ hash │ // │ │ │ ├──────────────┬──────┼──────────┬────────────────┤ │ // │ │ │ │ hostname │ port │ pathname │ search │ │ // │ │ │ │ │ │ ├─┬──────────────┤ │ // │ │ │ │ │ │ │ │ query │ │ // " https: // user : pass @ sub.host.com : 8080 /p/a/t/h ? query=string #hash " // │ │ │ │ │ hostname │ port │ │ │ │ // │ │ │ │ ├──────────────┴──────┤ │ │ │ // │ protocol │ │ username │ password │ host │ │ │ │ // ├──────────┴──┼──────────┴──────────┼─────────────────────┤ │ │ │ // │ origin │ │ origin │ pathname │ search │ hash │ // ├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤ // │ href │ // └─────────────────────────────────────────────────────────────────────────────────────────────┘
const {URL, URLSearchParams} = require('url'); const myURL = new URL('https://example.org/?abc=123'); console.log(myURL.searchParams.get('abc')); myURL.searchParams.append('abc', 'xyz'); myURL.searchParams.delete('abc'); myURL.searchParams.set('a', 'b'); const newSearchParams = new URLSearchParams(myURL.searchParams); newSearchParams.append('a', 'c'); myURL.search = newSearchParams; console.log(myURL.href);
const {URL, URLSearchParams} = require('url'); const myURL = new URL('https://example.org/?abc=123'); console.log(myURL.searchParams.get('abc')); myURL.searchParams.append('abc', 'xyz'); myURL.searchParams.delete('abc'); myURL.searchParams.set('a', 'b'); const newSearchParams = new URLSearchParams(myURL.searchParams); newSearchParams.append('a', 'c'); myURL.search = newSearchParams; console.log(myURL.href);
//在数组的形式中,重复的键是不允许的。 const params = new URLSearchParams({ user: 'abc', query: ['first', 'second'] }); console.log(params.getAll('query')); console.log(params.toString()); //iterable <Iterable> 一个元素时键值对的迭代对象 let params; // Using an array params = new URLSearchParams([ ['user', 'abc'], ['query', 'first'], ['query', 'second'] ]); console.log(params.toString()); // 输出 'user=abc&query=first&query=second' // 使用Map对象 const map = new Map(); map.set('user', 'abc'); map.set('query', 'xyz'); params = new URLSearchParams(map); console.log(params.toString()); // 输出 'user=abc&query=xyz' // 使用generator函数 function* getQueryPairs() { yield ['user', 'abc']; yield ['query', 'first']; yield ['query', 'second']; } params = new URLSearchParams(getQueryPairs()); console.log(params.toString()); // 输出 'user=abc&query=first&query=second' // 每个键值对必须有两个元素 new URLSearchParams([ ['user', 'abc', 'error'] ]); // 抛出 TypeError [ERR_INVALID_TUPLE]: // 每一个键值对必须是迭代的[键,值]元组
//在数组的形式中,重复的键是不允许的。 const params = new URLSearchParams({ user: 'abc', query: ['first', 'second'] }); console.log(params.getAll('query')); console.log(params.toString()); //iterable <Iterable> 一个元素时键值对的迭代对象 let params; // Using an array params = new URLSearchParams([ ['user', 'abc'], ['query', 'first'], ['query', 'second'] ]); console.log(params.toString()); // 输出 'user=abc&query=first&query=second' // 使用Map对象 const map = new Map(); map.set('user', 'abc'); map.set('query', 'xyz'); params = new URLSearchParams(map); console.log(params.toString()); // 输出 'user=abc&query=xyz' // 使用generator函数 function* getQueryPairs() { yield ['user', 'abc']; yield ['query', 'first']; yield ['query', 'second']; } params = new URLSearchParams(getQueryPairs()); console.log(params.toString()); // 输出 'user=abc&query=first&query=second' // 每个键值对必须有两个元素 new URLSearchParams([ ['user', 'abc', 'error'] ]); // 抛出 TypeError [ERR_INVALID_TUPLE]: // 每一个键值对必须是迭代的[键,值]元组