{"_id":"eventproxy","_rev":"88176","name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","dist-tags":{"latest":"1.0.0"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"time":{"modified":"2021-06-03T10:28:39.000Z","created":"2011-12-07T16:38:53.620Z","1.0.0":"2017-07-03T02:31:58.097Z","0.3.5":"2016-07-20T02:58:41.805Z","0.3.4":"2015-06-15T03:27:25.333Z","0.3.3":"2015-04-26T08:30:47.351Z","0.3.2":"2015-01-08T04:28:16.774Z","0.3.1":"2014-03-27T08:52:48.910Z","0.3.0":"2014-03-03T09:44:18.460Z","0.2.7":"2014-02-27T11:48:58.182Z","0.2.6":"2013-10-31T14:21:33.529Z","0.2.5":"2013-06-18T02:37:21.604Z","0.2.4":"2013-06-06T08:08:08.701Z","0.2.3":"2013-05-18T05:51:14.438Z","0.2.2":"2013-03-05T06:20:25.166Z","0.2.1":"2012-11-26T08:48:51.834Z","0.2.0":"2012-11-14T07:16:33.070Z","0.1.4":"2012-10-15T16:35:45.083Z","0.1.3":"2012-10-09T06:05:34.815Z","0.1.2":"2012-08-09T10:11:26.883Z","0.1.1":"2012-01-15T04:45:13.372Z","0.1.0":"2011-12-07T16:38:53.620Z"},"users":{"stonestyle":true,"summer":true,"zxx714":true,"solu":true,"maobean":true,"cgfeel":true,"nunn":true,"samhwang1990":true,"nickeljew":true,"tudou":true,"mastayoda":true,"dongxu":true,"liulei224":true,"leoyzy":true,"nanhualyq":true,"wangnan0610":true,"simdd":true,"rdmclin2":true,"caryfff":true,"hyteer":true,"kkk123321":true,"sternelee":true,"cath":true,"itnovicer":true,"carlhong":true,"qinkangwu":true,"glutton":true,"xingtao":true,"jacks":true,"fordream001":true,"jon_shen":true,"zhoutk":true,"jaxcode":true,"tomchao":true,"mecal":true,"modood":true,"kimi_xin":true,"superchenney":true,"stona":true,"aidenzou":true,"koreyhan":true},"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"versions":{"1.0.0":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"^2.6.8"},"devDependencies":{"autod":"*","browser":"0.2.6","chai":"3.2.0","contributors":"*","eventproxy":"0.3.4","growl":"1.8.1","istanbul":"*","jade":"1.11.0","mocha":"2.3.2","pedding":"1.0.0"},"scripts":{"test":"make test-all"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"1.0.0","main":"index.js","types":"index.d.ts","directories":{"doc":"doc","test":"test"},"license":"MIT","files":["index.js","index.d.ts","lib"],"gitHead":"90828274f176b4aa754d09ca3adc7ac1379c82b1","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@1.0.0","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"dist":{"shasum":"8f384890824e0c06c40dc3f59ce2444793821d99","size":12353,"noattachment":false,"key":"/eventproxy/-/eventproxy-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-1.0.0.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/eventproxy-1.0.0.tgz_1499049117894_0.6784739561844617"},"publish_time":1499049118097,"_cnpm_publish_time":1499049118097,"_hasShrinkwrap":false},"0.3.5":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"2.2.0"},"devDependencies":{"browser":"0.2.6","contributors":"*","growl":"1.9.2","istanbul":"*","mocha":"2.5.3","pedding":"1.0.0"},"scripts":{"test":"make test-all"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.3.5","main":"index.js","directories":{"test":"test"},"license":"MIT","spm":{"main":"index.js","ignore":["test"]},"files":["lib","index.js"],"gitHead":"410b8a2021be9e1ed6ae396483bfb2ebe34f223e","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.3.5","_shasum":"4db3290dcbc51cf067cbb6752e3c40b5d917212f","_from":".","_npmVersion":"2.15.1","_nodeVersion":"4.4.4","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"dist":{"shasum":"4db3290dcbc51cf067cbb6752e3c40b5d917212f","size":10722,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.3.5.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.3.5.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/eventproxy-0.3.5.tgz_1468983520153_0.16356190340593457"},"publish_time":1468983521805,"_cnpm_publish_time":1468983521805,"_hasShrinkwrap":false},"0.3.4":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"2.1.3"},"devDependencies":{"autod":"*","chai":"1.9.0","component":"*","contributors":"*","eventproxy":"0.2.7","growl":"1.7.0","jade":"1.3.0","mocha":"1.17.1","mocha-phantomjs":"*","pedding":"0.0.3","totoro":"*","istanbul":"*"},"scripts":{"test":"make test-all"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.3.4","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","spm":{"main":"index.js","ignore":["test"]},"gitHead":"30405813e0076f6c766fd774ae8584e2f5196fa0","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.3.4","_shasum":"f71964ed73c6dedc1ada72147808ccbc418cbbe1","_from":".","_npmVersion":"2.9.0","_nodeVersion":"2.0.0","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"dist":{"shasum":"f71964ed73c6dedc1ada72147808ccbc418cbbe1","size":42382,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.3.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.3.4.tgz"},"publish_time":1434338845333,"_cnpm_publish_time":1434338845333,"_hasShrinkwrap":false},"0.3.3":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"2.1.3"},"devDependencies":{"autod":"*","chai":"1.9.0","component":"*","contributors":"*","eventproxy":"0.2.7","growl":"1.7.0","jade":"1.3.0","mocha":"1.17.1","mocha-phantomjs":"*","pedding":"0.0.3","totoro":"*","istanbul":"*"},"scripts":{"test":"make test-all"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.3.3","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","spm":{"main":"index.js","ignore":["test"]},"gitHead":"ba69afaa9382062963d257809364eb3f724e70e7","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.3.3","_shasum":"447991098d7eca1e34041aca5375f4d74f773822","_from":".","_npmVersion":"2.7.6","_nodeVersion":"1.7.1","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"dist":{"shasum":"447991098d7eca1e34041aca5375f4d74f773822","size":42261,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.3.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.3.3.tgz"},"publish_time":1430037047351,"_cnpm_publish_time":1430037047351,"_hasShrinkwrap":false},"0.3.2":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"0.7.4"},"devDependencies":{"autod":"*","chai":"1.9.0","component":"*","contributors":"*","eventproxy":"0.2.7","growl":"1.7.0","jade":"1.3.0","mocha":"1.17.1","mocha-phantomjs":"*","pedding":"0.0.3","totoro":"*","istanbul":"*"},"scripts":{"test":"make test-all"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.3.2","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","gitHead":"e8d94127ea72d2abf6199103bae2022490c40a92","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.3.2","_shasum":"b1aaf9d89b150e9770e87343352172f49e5630aa","_from":".","_npmVersion":"1.4.21","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"dist":{"shasum":"b1aaf9d89b150e9770e87343352172f49e5630aa","size":42389,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.3.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.3.2.tgz"},"publish_time":1420691296774,"_cnpm_publish_time":1420691296774,"_hasShrinkwrap":false},"0.3.1":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"0.7.4"},"devDependencies":{"autod":"*","blanket":"*","chai":"1.9.0","component":"*","contributors":"*","eventproxy":"0.2.7","growl":"1.7.0","jade":"1.3.0","mocha":"1.17.1","mocha-phantomjs":"*","pedding":"0.0.3","totoro":"*","cov":"*"},"scripts":{"test":"make test-all"},"config":{"blanket":{"pattern":"eventproxy/lib","data-cover-flags":{"debug":false}},"travis-cov":{"threshold":97}},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.3.1","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.3.1","dist":{"shasum":"6a28b7ab131d04020c96b88a0ad29189a550eb98","size":15138,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.3.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.3.1.tgz"},"_from":".","_npmVersion":"1.4.3","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1395910368910,"_hasShrinkwrap":false,"_cnpm_publish_time":1395910368910},"0.3.0":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"0.7.4"},"devDependencies":{"autod":"*","blanket":"*","chai":"1.9.0","component":"*","contributors":"*","eventproxy":"0.2.7","growl":"1.7.0","jade":"1.3.0","mocha":"1.17.1","mocha-phantomjs":"*","pedding":"0.0.3","totoro":"*","cov":"*"},"scripts":{"test":"make test-all"},"config":{"blanket":{"pattern":"eventproxy/lib","data-cover-flags":{"debug":false}},"travis-cov":{"threshold":97}},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.3.0","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.3.0","dist":{"shasum":"fe28d1f0dcd4b07fca2087acc3d974757d3dbd2a","size":15139,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.3.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.3.0.tgz"},"_from":".","_npmVersion":"1.4.3","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1393839858460,"_hasShrinkwrap":false,"_cnpm_publish_time":1393839858460},"0.2.7":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"0.7.2"},"devDependencies":{"mocha":"*","mocha-phantomjs":"*","component":"*","blanket":"*","pedding":"*","chai":"*","travis-cov":"*"},"scripts":{"test":"make test-all"},"config":{"blanket":{"pattern":"eventproxy/lib","data-cover-flags":{"debug":false}},"travis-cov":{"threshold":97}},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.7","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.2.7","dist":{"shasum":"9b42a4f66ca9c83dd75cfec7e872c8735d476af6","size":14709,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.7.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.7.tgz"},"_from":".","_npmVersion":"1.3.24","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1393501738182,"_hasShrinkwrap":false,"_cnpm_publish_time":1393501738182},"0.2.6":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{"debug":"0.7.2"},"devDependencies":{"mocha":"*","mocha-phantomjs":"*","component":"*","blanket":"*","pedding":"*","chai":"*","travis-cov":"*"},"scripts":{"test":"make test-all"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.6","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.2.6","dist":{"shasum":"266bd26dd97deb7fa6935e3e2208c64f0d9bd016","size":14510,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.6.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.6.tgz"},"_from":".","_npmVersion":"1.3.11","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1383229293529,"_hasShrinkwrap":false,"_cnpm_publish_time":1383229293529},"0.2.5":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","blanket":"*","pedding":"*","chai":"*","travis-cov":"*"},"scripts":{"test":"make test-all","blanket":{"pattern":"eventproxy/lib","data-cover-flags":{"debug":false}},"travis-cov":{"threshold":70}},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.5","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.2.5","dist":{"shasum":"e234f94cb56f8c3e1ddb3d31f13aca48c0091c67","size":13861,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.5.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.5.tgz"},"_from":".","_npmVersion":"1.2.23","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1371523041604,"_hasShrinkwrap":false,"_cnpm_publish_time":1371523041604},"0.2.4":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","blanket":"*","pedding":"*","chai":"*","travis-cov":"*"},"scripts":{"test":"make test-all","blanket":{"pattern":"eventproxy/lib","data-cover-flags":{"debug":false}},"travis-cov":{"threshold":70}},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.4","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"_id":"eventproxy@0.2.4","dist":{"shasum":"759669e7573e53c706820b19097d0d6d54b09196","size":13816,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.4.tgz"},"_from":".","_npmVersion":"1.2.23","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1370506088701,"_hasShrinkwrap":false,"_cnpm_publish_time":1370506088701},"0.2.3":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","blanket":"*","pedding":"*","chai":"*","travis-cov":"*"},"scripts":{"test":"make test-all","blanket":{"pattern":"eventproxy/lib","data-cover-flags":{"debug":false}},"travis-cov":{"threshold":70}},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.3","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","_id":"eventproxy@0.2.3","dist":{"shasum":"db565d6437f243e580df1f5013ce8403e081a4d6","size":12298,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.3.tgz"},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1368856274438,"_hasShrinkwrap":false,"_cnpm_publish_time":1368856274438},"0.2.2":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","jscover":"*","pedding":"*","chai":"*"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.2","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","_id":"eventproxy@0.2.2","dist":{"shasum":"fb6fc354c5e59c7683bfe03dc1c8e6ac5a5a6124","size":9157,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.2.tgz"},"_from":".","_npmVersion":"1.2.2","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1362464425166,"_hasShrinkwrap":false,"_cnpm_publish_time":1362464425166},"0.2.1":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","jscover":"*","pedding":"*","chai":"*"},"scripts":{"test":"make test"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.1","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","_id":"eventproxy@0.2.1","dist":{"shasum":"8ada78b1990df253c09c26578e1e7514da6b4c8e","size":6518,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.1.tgz"},"_npmVersion":"1.1.65","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1353919731834,"_hasShrinkwrap":false,"_cnpm_publish_time":1353919731834},"0.2.0":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","jscover":"*","pedding":"*","chai":"*"},"scripts":{"test":"mocha test/test.js"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.2.0","main":"index.js","directories":{"doc":"doc","test":"test"},"license":"MIT","_id":"eventproxy@0.2.0","dist":{"shasum":"bacbd48cb775402afc990c212de8fcf636b1c1a5","size":6436,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.2.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.2.0.tgz"},"_npmVersion":"1.1.63","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"publish_time":1352877393070,"_hasShrinkwrap":false,"_cnpm_publish_time":1352877393070},"0.1.4":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"mocha":"*","chai":"*"},"scripts":{"test":"mocha test/test.js"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"version":"0.1.4","_id":"eventproxy@0.1.4","dist":{"shasum":"dfdda4047b83e936d74c117edddc2be46b1afa4a","size":81901,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.1.4.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.1.4.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"directories":{},"publish_time":1350318945083,"_hasShrinkwrap":false,"_cnpm_publish_time":1350318945083},"0.1.3":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"expresso":">= 0.9.2"},"scripts":{"test":"expresso test/eventproxy.test.js"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"main":"eventproxy.js","version":"0.1.3","_id":"eventproxy@0.1.3","dist":{"shasum":"6f2dc4638750418440ac7805161da1f933297222","size":20700,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.1.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.1.3.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"directories":{},"publish_time":1349762734815,"_hasShrinkwrap":false,"_cnpm_publish_time":1349762734815},"0.1.2":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"expresso":">= 0.9.2"},"scripts":{"test":"expresso test/eventproxy.test.js"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"main":"eventproxy.js","version":"0.1.2","_id":"eventproxy@0.1.2","dist":{"shasum":"c5b9a6c4ee666fb415e318d5f6e3239d7ae4a393","size":20577,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.1.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.1.2.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"directories":{},"publish_time":1344507086883,"_hasShrinkwrap":false,"_cnpm_publish_time":1344507086883},"0.1.1":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"expresso":">= 0.9.2"},"scripts":{"test":"expresso test/eventproxy.test.js"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"main":"eventproxy.js","version":"0.1.1","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"_id":"eventproxy@0.1.1","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.0-beta-4","_nodeVersion":"v0.6.6","_defaultsLoaded":true,"dist":{"shasum":"80b119d7bd5d2ed0b7e8ab4bb0a75898d2167e24","size":20889,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.1.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.1.1.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"directories":{},"publish_time":1326602713372,"_hasShrinkwrap":false,"_cnpm_publish_time":1326602713372},"0.1.0":{"name":"eventproxy","description":"An implementation of task/event based asynchronous pattern.","homepage":"https://github.com/JacksonTian/eventproxy","keywords":["event","task-base","event machine","nested callback terminator"],"author":{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},"contributors":[{"name":"Jackson Tian","email":"shyvo1987@gmail.com"},{"name":"fengmk2","email":"fengmk2@gmail.com"}],"dependencies":{},"devDependencies":{"expresso":">= 0.9.2"},"scripts":{"test":"expresso test/eventproxy.test.js"},"repository":{"type":"git","url":"git://github.com/JacksonTian/eventproxy.git"},"main":"eventproxy.js","version":"0.1.0","_npmUser":{"name":"jacksontian","email":"shyvo1987@gmail.com"},"_id":"eventproxy@0.1.0","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.0-alpha-6","_nodeVersion":"v0.6.4","_defaultsLoaded":true,"dist":{"shasum":"bf41d152280e3cd6a3d75de4da82c23cbc3b77cd","size":20823,"noattachment":false,"key":"/eventproxy/-/eventproxy-0.1.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/eventproxy/download/eventproxy-0.1.0.tgz"},"maintainers":[{"name":"jacksontian","email":"shyvo1987@gmail.com"}],"directories":{},"publish_time":1323275933620,"_hasShrinkwrap":false,"_cnpm_publish_time":1323275933620}},"readme":"EventProxy [![Build Status](https://secure.travis-ci.org/JacksonTian/eventproxy.png)](http://travis-ci.org/JacksonTian/eventproxy) [![NPM version](https://badge.fury.io/js/eventproxy.png)](http://badge.fury.io/js/eventproxy) [English Doc](https://github.com/JacksonTian/eventproxy/blob/master/README_en.md)\n======\n\n[![NPM](https://nodei.co/npm/eventproxy.png?downloads=true&stars=true)](https://nodei.co/npm/eventproxy)\n\n> 这个世界上不存在所谓回调函数深度嵌套的问题。 —— [Jackson Tian](http://weibo.com/shyvo)\n\n> 世界上本没有嵌套回调，写得人多了，也便有了`}}}}}}}}}}}}`。 —— [fengmk2](http://fengmk2.github.com)\n\n* API文档: [API Documentation](http://html5ify.com/eventproxy/api.html)\n* jscoverage: [97%](http://html5ify.com/eventproxy/coverage.html)\n* 源码注解：[注解文档](http://html5ify.com/eventproxy/eventproxy.html)\n\n\nEventProxy 仅仅是一个很轻量的工具，但是能够带来一种事件式编程的思维变化。有几个特点：\n\n1. 利用事件机制解耦复杂业务逻辑\n2. 移除被广为诟病的深度callback嵌套问题\n3. 将串行等待变成并行等待，提升多异步协作场景下的执行效率\n4. 友好的Error handling\n5. 无平台依赖，适合前后端，能用于浏览器和Node.js\n6. 兼容CMD，AMD以及CommonJS模块环境\n\n现在的，无深度嵌套的，并行的\n\n```js\nvar ep = EventProxy.create(\"template\", \"data\", \"l10n\", function (template, data, l10n) {\n  _.template(template, data, l10n);\n});\n\n$.get(\"template\", function (template) {\n  // something\n  ep.emit(\"template\", template);\n});\n$.get(\"data\", function (data) {\n  // something\n  ep.emit(\"data\", data);\n});\n$.get(\"l10n\", function (l10n) {\n  // something\n  ep.emit(\"l10n\", l10n);\n});\n```\n\n过去的，深度嵌套的，串行的。\n\n```js\nvar render = function (template, data) {\n  _.template(template, data);\n};\n$.get(\"template\", function (template) {\n  // something\n  $.get(\"data\", function (data) {\n    // something\n    $.get(\"l10n\", function (l10n) {\n      // something\n      render(template, data, l10n);\n    });\n  });\n});\n```\n## 安装\n### Node用户\n通过NPM安装即可使用：\n\n```bash\n$ npm install eventproxy\n```\n\n调用:\n\n```js\nvar EventProxy = require('eventproxy');\n```\n\n### [spm](http://spmjs.io/package/eventproxy)\n\n```bash\n$ spm install eventproxy\n```\n\n### Component\n\n```bash\n$ component install JacksonTian/eventproxy\n```\n\n### 前端用户\n以下示例均指向Github的源文件地址，您也可以[下载源文件](https://raw.github.com/JacksonTian/eventproxy/master/lib/eventproxy.js)到你自己的项目中。整个文件注释全面，带注释和空行，一共约500行。为保证EventProxy的易嵌入，项目暂不提供压缩版。用户可以自行采用Uglify、YUI Compressor或Google Closure Complier进行压缩。\n\n#### 普通环境\n在页面中嵌入脚本即可使用：\n\n```html\n<script src=\"https://raw.github.com/JacksonTian/eventproxy/master/lib/eventproxy.js\"></script>\n```\n使用：\n\n```js\n// EventProxy此时是一个全局变量\nvar ep = new EventProxy();\n```\n\n#### SeaJS用户\nSeaJS下只需配置别名，然后`require`引用即可使用。\n\n```js\n// 配置\nseajs.config({\n  alias: {\n    eventproxy: 'https://raw.github.com/JacksonTian/eventproxy/master/lib/eventproxy.js'\n  }\n});\n// 使用\nseajs.use(['eventproxy'], function (EventProxy) {\n  // TODO\n});\n// 或者\ndefine('test', function (require, exports, modules) {\n  var EventProxy = require('eventproxy');\n});\n```\n\n#### RequireJS用户\nRequireJS实现的是AMD规范。\n\n```js\n// 配置路径\nrequire.config({\n  paths: {\n    eventproxy: \"https://raw.github.com/JacksonTian/eventproxy/master/lib/eventproxy\"\n  }\n});\n// 使用\nrequire([\"eventproxy\"], function (EventProxy) {\n  // TODO\n});\n```\n## 异步协作\n### 多类型异步协作\n此处以页面渲染为场景，渲染页面需要模板、数据。假设都需要异步读取。\n\n```js\nvar ep = new EventProxy();\nep.all('tpl', 'data', function (tpl, data) { // or ep.all(['tpl', 'data'], function (tpl, data) {})\n  // 在所有指定的事件触发后，将会被调用执行\n  // 参数对应各自的事件名\n});\nfs.readFile('template.tpl', 'utf-8', function (err, content) {\n  ep.emit('tpl', content);\n});\ndb.get('some sql', function (err, result) {\n  ep.emit('data', result);\n});\n```\n\n`all`方法将handler注册到事件组合上。当注册的多个事件都触发后，将会调用handler执行，每个事件传递的数据，将会依照事件名顺序，传入handler作为参数。\n#### 快速创建\nEventProxy提供了`create`静态方法，可以快速完成注册`all`事件。\n\n```js\nvar ep = EventProxy.create('tpl', 'data', function (tpl, data) {\n  // TODO\n});\n```\n\n以上方法等效于\n\n```js\nvar ep = new EventProxy();\nep.all('tpl', 'data', function (tpl, data) {\n  // TODO\n});\n```\n\n### 重复异步协作\n此处以读取目录下的所有文件为例，在异步操作中，我们需要在所有异步调用结束后，执行某些操作。\n\n```js\nvar ep = new EventProxy();\nep.after('got_file', files.length, function (list) {\n  // 在所有文件的异步执行结束后将被执行\n  // 所有文件的内容都存在list数组中\n});\nfor (var i = 0; i < files.length; i++) {\n  fs.readFile(files[i], 'utf-8', function (err, content) {\n    // 触发结果事件\n    ep.emit('got_file', content);\n  });\n}\n```\n\n`after`方法适合重复的操作，比如读取10个文件，调用5次数据库等。将handler注册到N次相同事件的触发上。达到指定的触发数，handler将会被调用执行，每次触发的数据，将会按触发顺序，存为数组作为参数传入。\n\n### 持续型异步协作\n此处以股票为例，数据和模板都是异步获取，但是数据会持续刷新，视图会需要重新刷新。\n\n```js\nvar ep = new EventProxy();\nep.tail('tpl', 'data', function (tpl, data) {\n  // 在所有指定的事件触发后，将会被调用执行\n  // 参数对应各自的事件名的最新数据\n});\nfs.readFile('template.tpl', 'utf-8', function (err, content) {\n  ep.emit('tpl', content);\n});\nsetInterval(function () {\n  db.get('some sql', function (err, result) {\n    ep.emit('data', result);\n  });\n}, 2000);\n```\n\n`tail`与`all`方法比较类似，都是注册到事件组合上。不同在于，指定事件都触发之后，如果事件依旧持续触发，将会在每次触发时调用handler，极像一条尾巴。\n\n\n## 基本事件\n通过事件实现异步协作是EventProxy的主要亮点。除此之外，它还是一个基本的事件库。携带如下基本API\n\n- `on`/`addListener`，绑定事件监听器\n- `emit`，触发事件\n- `once`，绑定只执行一次的事件监听器\n- `removeListener`，移除事件的监听器\n- `removeAllListeners`，移除单个事件或者所有事件的监听器\n\n为了照顾各个环境的开发者，上面的方法多具有别名。\n\n- YUI3使用者，`subscribe`和`fire`你应该知道分别对应的是`on`/`addListener`和`emit`。\n- jQuery使用者，`trigger`对应的方法是`emit`，`bind`对应的就是`on`/`addListener`。\n- `removeListener`和`removeAllListeners`其实都可以通过别名`unbind`完成。\n\n所以在你的环境下，选用你喜欢的API即可。\n\n更多API的描述请访问[API Docs](http://html5ify.com/eventproxy/api.html)。\n\n## 异常处理\n在异步方法中，实际上，异常处理需要占用一定比例的精力。在过去一段时间内，我们都是通过额外添加`error`事件来进行处理的，代码大致如下：\n\n```js\nexports.getContent = function (callback) {\n var ep = new EventProxy();\n  ep.all('tpl', 'data', function (tpl, data) {\n    // 成功回调\n    callback(null, {\n      template: tpl,\n      data: data\n    });\n  });\n  // 侦听error事件\n  ep.bind('error', function (err) {\n    // 卸载掉所有handler\n    ep.unbind();\n    // 异常回调\n    callback(err);\n  });\n  fs.readFile('template.tpl', 'utf-8', function (err, content) {\n    if (err) {\n      // 一旦发生异常，一律交给error事件的handler处理\n      return ep.emit('error', err);\n    }\n    ep.emit('tpl', content);\n  });\n  db.get('some sql', function (err, result) {\n    if (err) {\n      // 一旦发生异常，一律交给error事件的handler处理\n      return ep.emit('error', err);\n    }\n    ep.emit('data', result);\n  });\n};\n```\n\n代码量因为异常的处理，一下子上去了很多。在这里EventProxy经过很多实践后，我们根据我们的最佳实践提供了优化的错误处理方案。\n\n```js\nexports.getContent = function (callback) {\n var ep = new EventProxy();\n  ep.all('tpl', 'data', function (tpl, data) {\n    // 成功回调\n    callback(null, {\n      template: tpl,\n      data: data\n    });\n  });\n  // 添加error handler\n  ep.fail(callback);\n\n  fs.readFile('template.tpl', 'utf-8', ep.done('tpl'));\n  db.get('some sql', ep.done('data'));\n};\n```\n\n上述代码优化之后，业务开发者几乎不用关心异常处理了。代码量降低效果明显。\n这里代码的转换，也许有开发者并不放心。其实秘诀在`fail`方法和`done`方法中。\n\n### 神奇的fail\n\n```js\nep.fail(callback);\n// 由于参数位相同，它实际是\nep.fail(function (err) {\n  callback(err);\n});\n\n// 等价于\nep.bind('error', function (err) {\n  // 卸载掉所有handler\n  ep.unbind();\n  // 异常回调\n  callback(err);\n});\n```\n\n`fail`方法侦听了`error`事件，默认处理卸载掉所有handler，并调用回调函数。\n\n### 神奇的 throw\n\n`throw` 是 `ep.emit('error', err)` 的简写。\n\n```js\nvar err = new Error();\nep.throw(err);\n// 实际是\nep.emit('error', err);\n```\n\n### 神奇的done\n\n```js\nep.done('tpl');\n// 等价于\nfunction (err, content) {\n  if (err) {\n    // 一旦发生异常，一律交给error事件的handler处理\n    return ep.emit('error', err);\n  }\n  ep.emit('tpl', content);\n}\n```\n\n在Node的最佳实践中，回调函数第一个参数一定会是一个`error`对象。检测到异常后，将会触发`error`事件。剩下的参数，将触发事件，传递给对应handler处理。\n\n#### done也接受回调函数\n`done`方法除了接受事件名外，还接受回调函数。如果是函数时，它将剔除第一个`error`对象(此时为`null`)后剩余的参数，传递给该回调函数作为参数。该回调函数无需考虑异常处理。\n\n```js\nep.done(function (content) {\n  // 这里无需考虑异常\n  // 手工emit\n  ep.emit('someevent', newcontent);\n});\n```\n\n当然手工emit的方式并不太好，我们更进一步的版本：\n\n```js\nep.done('tpl', function (tpl) {\n  // 将内容更改后，返回即可\n  return tpl.trim();\n});\n```\n\n#### 注意事项\n如果`emit`需要传递多个参数时，`ep.done(event, fn)`的方式不能满足需求，还是需要`ep.done(fn)`，进行手工`emit`多个参数。\n\n### 神奇的group\n`fail`除了用于协助`all`方法完成外，也能协助`after`中的异常处理。另外，在`after`的回调函数中，结果顺序是与用户`emit`的顺序有关。为了满足返回数据按发起异步调用的顺序排列，`EventProxy`提供了`group`方法。\n\n```js\nvar ep = new EventProxy();\nep.after('got_file', files.length, function (list) {\n  // 在所有文件的异步执行结束后将被执行\n  // 所有文件的内容都存在list数组中，按顺序排列\n});\nfor (var i = 0; i < files.length; i++) {\n  fs.readFile(files[i], 'utf-8', ep.group('got_file'));\n}\n```\n`group`秉承`done`函数的设计，它包含异常的传递。同时它还隐含了对返回数据进行编号，在结束时，按顺序返回。\n\n```js\nep.group('got_file');\n// 约等价于\nfunction (err, data) {\n  if (err) {\n    return ep.emit('error', err);\n  }\n  ep.emit('got_file', data);\n};\n```\n\n当回调函数的数据还需要进行加工时，可以给`group`带上回调函数，只要在操作后将数据返回即可：\n\n```js\nep.group('got_file', function (data) {\n  // some code\n  return data;\n});\n```\n\n### 异步事件触发: emitLater && doneLater\n\n在node中，`emit`方法是同步的，EventProxy中的`emit`，`trigger`等跟node的风格一致，也是同步的。看下面这段代码，可能眼尖的同学一下就发现了隐藏的bug:\n```js\nvar ep = EventProxy.create();\n\ndb.check('key', function (err, permission) {\n  if (err) {\n    return ep.emit('error', err);\n  }\n  ep.emit('check', permission);\n});\n\nep.once('check', function (permission) {\n  permission && db.get('key', function (err, data) {\n    if (err) {\n      return ep.emit('error');\n    }\n    ep.emit('get', data);\n  });\n});\n\nep.once('get', function (err, data) {\n  if (err) {\n    return ep.emit('error', err);\n  }\n  render(data);\n});\n\nep.on('error', errorHandler);\n```\n\n没错，万一`db.check`的`callback`被同步执行了，在`ep`监听`check`事件之前，它就已经被抛出来了，后续逻辑没办法继续执行。尽管node的约定是所有的`callback`都是需要异步返回的，但是如果这个方法是由第三方提供的，我们没有办法保证`db.check`的`callback`一定会异步执行，所以我们的代码通常就变成了这样:\n\n```js\nvar ep = EventProxy.create();\n\nep.once('check', function (permission) {\n  permission && db.get('key', function (err, data) {\n    if (err) {\n      return ep.emit('error');\n    }\n    ep.emit('get', data);\n  });\n});\n\nep.once('get', function (err, data) {\n  if (err) {\n    return ep.emit('error', err);\n  }\n  render(data);\n});\n\nep.on('error', errorHandler);\n\ndb.check('key', function (err, permission) {\n  if (err) {\n    return ep.emit('error', err);\n  }\n  ep.emit('check', permission);\n});\n```\n我们被迫把`db.check`挪到最后，保证事件先被监听，再执行`db.check`。`check`->`get`->`render`的逻辑，在代码中看起来变成了`get`->`render`->`check`。如果整个逻辑更加复杂，这种风格将会让代码很难读懂。\n\n这时候，我们需要的就是 __异步事件触发__：\n\n```js\nvar ep = EventProxy.create();\n\ndb.check('key', function (err, permission) {\n  if (err) {\n    return ep.emitLater('error', err);\n  }\n  ep.emitLater('check', permission);\n});\n\nep.once('check', function (permission) {\n  permission && db.get('key', function (err, data) {\n    if (err) {\n      return ep.emit('error');\n    }\n    ep.emit('get', data);\n  });\n});\n\nep.once('get', function (err, data) {\n  if (err) {\n    return ep.emit('error', err);\n  }\n  render(data);\n});\n\nep.on('error', errorHandler);\n```\n上面代码中，我们把`db.check`的回调函数中的事件通过`emitLater`触发，这样,就算`db.check`的回调函数被同步执行了，事件的触发也还是异步的，`ep`在当前事件循环中监听了所有的事件，之后的事件循环中才会去触发`check`事件。代码顺序将和逻辑顺序保持一致。\n当然，这么复杂的代码，必须可以像`ep.done()`一样通过`doneLater`来解决：\n\n```js\nvar ep = EventProxy.create();\n\ndb.check('key', ep.doneLater('check'));\n\nep.once('check', function (permission) {\n  permission && db.get('key', ep.done('get'));\n});\n\nep.once('get', function (data) {\n  render(data);\n});\n\nep.fail(errorHandler);\n```\n最终呈现出来的，是一段简洁且清晰的代码。\n\n\n## 注意事项\n- 请勿使用`all`作为业务中的事件名。该事件名为保留事件。\n- 异常处理部分，请遵循 Node 的最佳实践(回调函数首个参数为异常传递位)。\n\n## 贡献者们\n谢谢 EventProxy 的使用者们，享受 EventProxy 的过程，也给 EventProxy 回馈良多。\n\n```bash\n project  : eventproxy\n repo age : 3 years, 6 months\n active   : 97 days\n commits  : 203\n files    : 24\n authors  :\n   177  Jackson Tian            87.2%\n     9  fengmk2                 4.4%\n     7  dead-horse              3.4%\n     2  azrael                  1.0%\n     2  rogerz                  1.0%\n     1  Bitdeli Chef            0.5%\n     1  yaoazhen                0.5%\n     1  Ivan Yan                0.5%\n     1  cssmagic                0.5%\n     1  haoxin                  0.5%\n     1  redky                   0.5%\n```\n\n详情请参见<https://github.com/JacksonTian/eventproxy/graphs/contributors>\n\n## License\n\n[The MIT License](https://github.com/JacksonTian/eventproxy/blob/master/MIT-License)。请自由享受开源。\n\n## 捐赠\n如果您觉得本模块对您有帮助，欢迎请作者一杯咖啡\n\n![捐赠EventProxy](https://cloud.githubusercontent.com/assets/327019/2941591/2b9e5e58-d9a7-11e3-9e80-c25aba0a48a1.png)\n","_attachments":{},"homepage":"https://github.com/JacksonTian/eventproxy","bugs":{"url":"https://github.com/JacksonTian/eventproxy/issues"},"license":"MIT"}