Last active
October 17, 2016 07:27
-
-
Save leizongmin/5a72de9fe99aaa429b29ae6b256ed6d7 to your computer and use it in GitHub Desktop.
利用generator与promise实现coroutine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// 检查是否为Promise对象 | |
function isPromise(p) { | |
return typeof p.then === 'function' && typeof p.catch === 'function'; | |
} | |
// coroutine包装函数 | |
function cotoutineWrap(genFn) { | |
const fn = function () { | |
return new Promise((resolve, reject) => { | |
const gen = genFn.apply(null, arguments); | |
function next(value) { | |
const ret = gen.next(value); | |
// 如果done=true则表示结束 | |
if (ret.done) return resolve(ret.value); | |
// 如果是promise则执行 | |
if (isPromise(ret.value)) return ret.value.then(next).catch(reject); | |
// 其他值则直接跳过 | |
next(); | |
} | |
// 开始执行 | |
next(); | |
}); | |
}; | |
// 保留函数名和参数信息 | |
const info = genFn.toString().match(/function\s*\*\s*(.*\(.*\))/); | |
const sign = info && info[1] ? info[1] : '()'; | |
const code = `(function ${sign} { return fn.apply(this, arguments); })`; | |
return eval(code); | |
} | |
// 以下是测试代码 ---------------------------------------------------------------- | |
function sleep(ms) { | |
return new Promise((resolve, reject) => { | |
console.log('sleep', ms); | |
setTimeout(resolve, ms); | |
// throw new Error('haha'); | |
}); | |
} | |
cotoutineWrap(function* (n) { | |
yield n; | |
for (let i = 0; i < n; i++) { | |
yield sleep(i * 200); | |
} | |
yield n; | |
return n; | |
})(5) | |
.then(ret => console.log('result', ret)) | |
.catch(err => console.log('error', err)); | |
console.log(cotoutineWrap(function* () { yield 123; }).toString()); | |
console.log(cotoutineWrap(function* abc() { yield 123; }).toString()); | |
console.log(cotoutineWrap(function* abc(a, b, c) { yield 123; }).toString()); | |
console.log(cotoutineWrap(function * abc(a, b, c) { yield 123; }).toString()); | |
console.log(cotoutineWrap(function * abc ( a, b, c ) { yield 123; }).toString()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment