Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Koa¿ò¼Üʵ¼ùÓëÖмä¼þÔ­ÀíÆÊÎö
 
  1666  次浏览      30
  2019-1-9
 
±à¼­ÍƼö:
±¾ÎÄÀ´×Ôcnblogs£¬ÎÄÕ½éÉÜÁËKoa¿ò¼Ü¡¢KoaµÄÖмä¼þÖ´ÐÐÒÔ¼°koaµÄÖмä¼þÊÇÔõôʵÏֵĵÈÏà¹ØÄÚÈÝ¡£

×î½ü³¢ÊÔÓÃÁËÒ»ÏÂKoa£¬²¢Ôڴ˼ǼһÏÂʹÓÃÐĵá£

×¢Ò⣺±¾ÎÄÊÇÒÔ¶ÁÕßÒѾ­Á˽âGeneratorºÍPromiseΪǰÌáÔÚдµÄ£¬ÒòΪµ¥µ¥GeneratorºÍPromise¶¼Äܹ»Ð´Ò»Æª²©ÎÄÀ´½²½â½éÉÜÁË£¬ËùÒԾͲ»ÔÚÕâÀï׸Êö¡£ÍøÉÏ×ÊÁϺܶ࣬¿ÉÒÔ×ÔÐвéÔÄ¡£

KoaÊÇExpressÔ­°àÈËÂí´òÔìµÄÒ»¸ö¸üС£¬»ùÓÚnodejsƽ̨µÄÏÂÒ»´úweb¿ª·¢¿ò¼Ü¡£KoaµÄ¾«ÃîÖ®´¦¾ÍÔÚÓÚÆäʹÓÃgeneratorºÍpromise£¬ÊµÏÖÁËÒ»ÖÖ¸üΪÓÐȤµÄÖмä¼þϵͳ£¬KoaµÄÖмä¼þÊÇһϵÁÐgeneratorº¯ÊýµÄ¶ÔÏó£¬Ö´ÐÐÆðÀ´ÓеãÀàËÆÓÚÕ»µÄ½á¹¹£¬ÒÀ´ÎÖ´ÐС£Í¬Ê±Ò²ÀàËÆÓÚPythonµÄdjango¿ò¼ÜµÄÖмä¼þϵͳ£¬ÒÔǰËÕǧ´óÉñ×ö·ÖÏíµÄʱºò°ÑÕâÖÖÄ£ÐͳÆ×÷ΪÑó´ÐÄ£ÐÍ¡£Èçͼ£º

¡¡¡¡

µ±Ò»¸öÇëÇó¹ýÀ´µÄʱºò£¬»áÒÀ´Î¾­¹ý¸÷¸öÖмä¼þ½øÐд¦Àí£¬Öмä¼þÌø×ªµÄÐźÅÊÇyield next£¬µ±µ½Ä³¸öÖмä¼þºó£¬¸ÃÖмä¼þ´¦ÀíÍê²»Ö´ÐÐyield nextµÄʱºò£¬È»ºó¾Í»áÄæÐòÖ´ÐÐÇ°ÃæÄÇЩÖмä¼þʣϵÄÂß¼­¡£Ö±½ÓÉϸö¹ÙÍøµÄÀý×Ó£º

var koa = require('koa');
var app = koa();

// response-timeÖмä¼þ
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
});

// loggerÖмä¼þ
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
console.log('%s %s - %s', this.method, this.url, ms);
});

// ÏìÓ¦Öмä¼þ
app.use(function *(){
this.body = 'Hello World';
});

app.listen(3000);

ÉÏÃæµÄÖ´ÐÐ˳Ðò¾ÍÊÇ£ºÇëÇó ==> response-timeÖмä¼þ ==> loggerÖмä¼þ ==> ÏìÓ¦Öмä¼þ ==> loggerÖмä¼þ ==> response-timeÖмä¼þ ==> ÏìÓ¦¡£

¸üÏêϸÃèÊö¾ÍÊÇ£ºÇëÇó½øÀ´£¬ÏȽøµ½response-timeÖмä¼þ£¬Ö´ÐÐ var start = new Date; È»ºóÓöµ½yield next£¬ÔòÔÝÍ£response-timeÖмä¼þµÄÖ´ÐУ¬Ìø×ª½øloggerÖмä¼þ£¬Í¬Àí£¬×îºó½øÈëÏìÓ¦Öмä¼þ£¬ÏìÓ¦Öмä¼þÖÐûÓÐyield next´úÂ룬Ôò¿ªÊ¼ÄæÐòÖ´ÐУ¬Ò²¾ÍÊÇÔÙÏÈÊǻص½loggerÖмä¼þ£¬Ö´ÐÐyield nextÖ®ºóµÄ´úÂ룬ִÐÐÍêºóÔٻص½response-timeÖмä¼þÖ´ÐÐyield nextÖ®ºóµÄ´úÂë¡£

ÖÁ´Ë£¬Õû¸öKoaµÄÖмä¼þÖ´ÐÐÍê±Ï £¬Õû¸öÖмä¼þÖ´Ðйý³ÌÏ൱ÓÐÒâ˼¡£

¶øKoaµÄÖмä¼þÊÇÔËÐÐÔÚ co º¯ÊýÏµģ¬¶øtj´óÉñµÄcoº¯ÊýÄܹ»°ÑÒì²½±äͬ²½£¬Ò²¾Í˵£¬±àдKoaµÄÖмä¼þµÄʱºò¿ÉÒÔÕâÑùд£¬¾ÍÄÃÉÏÃæÄǸödemo×îºóµÄÏìÓ¦Öмä¼þÀ´Ëµ¿ÉÒԸijÉÕâÑù£º

app.use(function*(){
var text = yield new Promise(function(resolve){
fs.readFile('./index.html', 'utf-8', function(err, data){
resolve(data);
})
});

this.body = text;
});

ͨ¹ýPromise¿ÉÒÔ°Ñ»ñÈ¡µÄÎļþÊý¾Ýdataͨ¹ýresolveº¯Êý£¬´«µ½×îÍâ²ãµÄtextÖУ¬¶øÇÒ£¬Õû¸öÒì²½²Ù×÷±ä³ÉÁËͬ²½²Ù×÷¡£

ÔÙ±ÈÈçʹÓÃmongodb×öÒ»¸öÊý¾Ý¿â²éѯ¹¦ÄÜ£¬¾Í¿ÉÒÔд³ÉÕâÑù£¬Õû¸öÊý¾ÝµÄ²éѯԭÀ´ÊÇÒì²½²Ù×÷£¬Ò²¿ÉÒÔ±ä³ÉÁËͬ²½£¬ÒòΪmongodb¹Ù·½Çý¶¯µÄ½Ó¿ÚÌṩÁË·µ»ØPromiseµÄ¹¦ÄÜ£¬ÔÚcoº¯ÊýÀïÖ»ÓÃyieldµÄʱºòÄܹ»Ö±½Ó°ÑÒì²½±ä³Éͬ²½£¬ÔÙÒ²²»ÓÃдÄǶñÐĵĻص÷ǶÌ×ÁË¡£

var MongoClient = require("mongodb").MongoClient;
app.use(function *(){
var db = yield MongoClient.connect('mongodb://127.0.0.1:27017/myblog');

var collection = db.collection('document');

var result = yield collection.find({}).toArray();

db.close()
});

tjµÄcoº¯Êý¾ÍÈçͬһ¸öħ·¨£¬°ÑËùÓÐÒì²½¶¼±ä³ÉÁËͬ²½£¬¿´ÆðÀ´ºÃÏñºÜ¸ß´óÉÏ¡£µ«ÊÇcoº¯Êý×öµÄÊÂÆäʵ²¢²»¸´ÔÓ¡£

Õû¸öcoº¯Êý˵°×ÁË£¬¾ÍÊÇʹÓÃPromiseµÝ¹éµ÷ÓÃgeneratorµÄnext·½·¨£¬²¢ÇÒÔÚºóÒ»´Îµ÷ÓõÄʱºò°Ñǰһ´Î·µ»ØµÄÊý¾Ý´«È룬ֱµ½µ÷ÓÃÍê±Ï¡£¶øcoº¯Êýͬʱ°Ñ·ÇPromise¶ÔÏóµÄfunction¡¢generator¡¢arrayµÈÒ²×é×°³ÉÁËPromise¶ÔÏó¡£ËùÒÔ¿ÉÒÔÔÚyieldºóÃæ²»½ö½ö¿ÉÒÔ½ÓPromise£¬»¹¿ÉÒÔ½Ógenerator¶ÔÏóµÈ¡£

×Ô¼ºÊµÏÖÁËÒ»¸ö¼òµ¥µÄcoº¯Êý£¬´«ÈëÒ»¸ögenerator£¬»ñÈ¡generatorµÄº¯Êý¶ÔÏó£¬È»ºó¶¨ÒåÒ»¸önext·½·¨ÓÃÓڵݹ飬ÔÚnext·½·¨ÀïÖ´ÐÐgenerator.next()²¢ÇÒ´«Èëdata£¬Ö´ÐÐÍêgenerator.next()»á»ñÈ¡µ½{value:XX, done: true|false}µÄ¶ÔÏó£¬Èç¹ûdoneΪtrue£¬ËµÃ÷generatorÒѾ­µü´úÍê±Ï£¬Í˳ö¡£

·ñÔò£¬¼ÙÉ赱ǰִÐе½yield new Promise()£¬Ò²¾ÍÊÇ·µ»ØµÄresult.value¾ÍÊÇPromise¶ÔÏóµÄ£¬Ö±½ÓÖ´ÐÐPromiseµÄthen·½·¨£¬²¢ÇÒÔÚthen·½·¨µÄonFulfilled»Øµ÷£¨Ò²¾ÍÊÇPromiseÖеÄÒì²½Ö´ÐÐÍê±Ïºó£¬µ÷ÓÃresolveµÄʱºò»á´¥·¢¸Ã»Øµ÷º¯Êý£©ÖÐÖ´ÐÐnext·½·¨½øÐеݹ飬²¢ÇÒ½«onFulfilledÖд«ÈëµÄÊý¾Ý´«Èënext·½·¨£¬Ò²¾Í¿ÉÒÔÔÚÏÂÒ»´Îgenerator.next()ÖаÑÊý¾Ý´«½øÈ¥¡£

// co¼òÒ×ʵÏÖ
function co(generator){
var gen = generator();

var next = function(data){
var result = gen.next(data);

if(result.done) return;

if (result.value instanceof Promise) {
result.value.then(function (d) {
next(d);
}, function (err) {
next(err);
})
}else {
next();
}
};

next();
}

д¸ödemo²âÊÔһϣº

// test
co(function*(){
var text1 = yield new Promise(function(resolve){
setTimeout(function(){
resolve("I am text1");
}, 1000);
});

console.log(text1);

var text2 = yield new Promise(function(resolve){
setTimeout(function(){
resolve("I am text2");
}, 1000);
});

console.log(text2);
});

ÔËÐнá¹û£º

ÔËÐгɹ¦£¡

¼ÈÈ»Á˽âÁËcoº¯ÊýµÄÔ­Àí£¬ÔÙÀ´ËµËµkoaµÄÖмä¼þÊÇÔõôʵÏֵġ£Õû¸öʵÏÖÔ­Àí¾ÍÊǰÑËùÓÐgenerator·Åµ½Ò»¸öÊý×éÀï±£´æ£¬È»ºó¶ÔËùÓÐgenerator½øÐÐÏàÓ¦µÄÁ´Ê½µ÷Óá£

Æð³õÊÇ×Ô¼º°´ÕÕ×Ô¼ºµÄÏ뷨ʵÏÖÁËÒ»´Î£¬´ó¸ÅÔ­ÀíÈçÏ£º

ÓøöÊý×飬ÔÚÿ´ÎÖ´ÐÐuse·½·¨µÄʱºò°Ñgenerator´«ÈëgensÊý×é±£´æ£¬È»ºóÔÚÖ´ÐеÄʱºò£¬Ïȶ¨ÒåÒ»¸ögeneratorµÄÖ´ÐÐË÷Òýindex¡¢Ìø×ª±ê¼Çne£¨Ò²¾ÍÊÇyield nextÀïµÄnext£©¡¢»¹ÓÐÒ»¸öÊÇÓÃÓÚ±£´ægeneratorº¯Êý¶ÔÏóµÄÊý×égs£¬¡£È»ºó»ñÈ¡µ±Ç°Öмä¼þgenerator£¬²¢ÇÒ»ñÈ¡µ½¸ÃgeneratorµÄº¯Êý¶ÔÏ󣬽«º¯Êý¶ÔÏó·ÅÈëgsÊý×éÖб£´æ£¬ÔÙÖ´ÐÐgenerator.next()¡£

½Óןù¾Ý·µ»ØµÄvalue£¬×ö²»Í¬´¦Àí£¬Èç¹ûÊÇPromise£¬Ôò¸úÉÏÃæµÄcoº¯ÊýÒ»Ñù£¬ÔÚÆäonFulfilledµÄ»Øµ÷ÖÐÖ´ÐÐÏÂÒ»´Îgenerator.next()£¬Èç¹ûÊÇne£¬Ò²¾ÍÊǵ±Ç°Ö´Ðе½ÁËyield next£¬ËµÃ÷ÒªÌø×ªµ½ÏÂÒ»¸öÖмä¼þ£¬´Ëʱ¶Ôindex++£¬È»ºó´ÓgensÊý×éÀï»ñÈ¡ÏÂÒ»¸öÖмä¼þÖØ¸´ÉÏÒ»¸öÖмä¼þµÄ²Ù×÷¡£

µ±Ö´Ðе½µÄÖмä¼þÀïûÓÐyield nextʱ£¬²¢ÇÒµ±¸ÃgeneratorÒѾ­Ö´ÐÐÍê±Ï£¬Ò²¾ÍÊÇ·µ»ØµÄdoneΪtrueµÄʱºò£¬ÔÙÄæÐòÖ´ÐУ¬´Ó´ËǰÓÃÓÚ±£´ægeneratorµÄº¯Êý¶ÔÏógsÊý×é»ñÈ¡µ½ÉÏÒ»¸ögeneratorº¯Êý¶ÔÏó£¬È»ºóÖ´ÐиÃgeneratorµÄnext·½·¨¡£Ö±µ½È«²¿Ö´ÐÐÍê±Ï¡£

Õû¸ö¹ý³Ì¾ÍÏñ£¬ÏÈÊÇÈëÕ»£¬È»ºó³öÕ»µÄ²Ù×÷¡£

//¼òÒ×ʵÏÖkoaµÄÖмä¼þЧ¹û

var gens = [];

function use(generetor){
gens.push(generetor);
}

function trigger(){
var index = 0;
var ne = {};
var gs = [],
g;

next();

function next(){
//»ñÈ¡µ±Ç°Öмä¼þ£¬´«Èënext±ê¼Ç£¬¼´µ±yield nextʱ´¦ÀíÏÂÒ»¸öÖмä¼þ
var gen = gens[index](ne);

//±£´æÊµÀý»¯µÄÖмä¼þ
gs.push(gen);

co(gen)
}

function co(gen, data){
if(!gen) return;

var result = gen.next(data);

// µ±µ±Ç°µÄgeneratorÖмä¼þÖ´ÐÐÍê±Ï£¬½«Ö´ÐÐË÷Òý¼õÒ»£¬»ñÈ¡ÉÏÒ»¼¶µÄÖмä¼þ²¢ÇÒÖ´ÐÐ
if(result.done){
index--;

if(g = gs[index]){
co(g);
}

return;
}

// Èç¹ûÖ´Ðе½Promise£¬Ôòµ±PromiseÖ´ÐÐÍê±ÏÔÙ½øÐеݹé
if(result.value instanceof Promise){
result.value.then(function(data){
co(gen, data);
})
}else if(result.value === ne){
// µ±Óöµ½yield nextʱ£¬Ö´ÐÐÏÂÒ»¸öÖмä¼þ
index++;

next();
}else {
co(gen);
}
}
}

 

È»ºóÔÙд¸ödemo²âÊÔһϣº

// test

use(function*(next){
var d = yield new Promise(function(resolve){
setTimeout(function(){
resolve("step1")
}, 1000)
});

console.log(d);

yield next;

console.log("step2");
});

use(function*(next){
console.log("step3");

yield next;

var d = yield new Promise(function(resolve){
setTimeout(function(){
resolve("step4")
}, 1000)
});

console.log(d);
});

use(function*(){
var d = yield new Promise(function(resolve){
setTimeout(function(){
resolve("step5")
}, 1000)
});

console.log(d);

console.log("step6");
});

trigger();

ÔËÐнá¹û£º

ÔËÐгɹ¦£¡

ÉÏÃæµÄÖ»ÊÇÎÒ×Ô¼ºµÄ¾õµÃµÄʵÏÖÔ­Àí£¬µ«ÊÇÆäʵkoa×Ô¼ºµÄʵÏÖ¸ü¾«¼ò£¬ÔÚ¿´ÁËkoaµÄÔ´Âëºó£¬Ò²´ó¸ÅʵÏÖÁËһϣ¬Æäʵ¾ÍÊǰÑÉÏÃæµÄÄǸöcoº¯Êý½øÐÐÊʵ±¸ÄÔìһϣ¬È»ºóÓøöwhileÑ­»·£¬°ÑËùÓÐgeneratorÁ´Ê½°ó¶¨ÆðÀ´£¬Ôٷŵ½coº¯ÊýÀï½øÐÐyield¼´¿É¡£ÏÂÃæÌù³öÔ´Â룺

var gens = [];

function use(generetor){
gens.push(generetor);
}

// ʵÏÖcoº¯Êý
function co(flow, isGenerator){
var gen;

if (isGenerator) {
gen = flow;
} else {
gen = flow();
}

return new Promise(function(resolve){
var next = function(data){
var result = gen.next(data);
var value = result.value;

// Èç¹ûµ÷ÓÃÍê±Ï£¬µ÷ÓÃresolve
if(result.done){
resolve(value);
return;
}

// Èç¹ûΪyieldºóÃæ½ÓµÄΪgenerator£¬´«Èëco½øÐеݹ飬²¢ÇÒ½«promise·µ»Ø
if (typeof value.next === "function" && typeof value.throw === "function") {
value = co(value, true);
}

if(value.then){
// µ±promiseÖ´ÐÐÍê±Ï£¬µ÷ÓÃnext´¦ÀíÏÂÒ»¸öyield
value.then(function(data){
next(data);
})
}
};

next();
});

}

function trigger(){
var prev = null;
var m = gens.length;
co(function*(){
while(m--){
// ÐγÉÁ´Ê½generator
prev = gens[m].call(null, prev);
}

// Ö´ÐÐ×îÍâ²ãgenerator·½·¨
yield prev;
})
}

Ö´Ðнá¹ûÒ²ÊÇÎÞÎÊÌ⣬ÔËÐÐdemoºÍÔËÐнá¹û¸úÉÏÒ»¸öÒ»Ñù£¬¾Í²»Ìù³öÀ´ÁË¡£

ÉÏÃæÐ´µÄÈý¸ö´úÂë·ÅÔÚÁËgithub£º

https://github.com/whxaxes/node-test/blob/master/other/myco.js

https://github.com/whxaxes/node-test/blob/master/other/mykoa.js

https://github.com/whxaxes/node-test/blob/master/other/mykoa_2.js

Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì

   
1666 ´Îä¯ÀÀ       30