问题描述
我的代码是这样的
const co = require(’co’);function are(){}function* abc(){ var a = yield are() console.log(1) var b = yield are() console.log(2) var c = yield are() console.log(3)}co(abc)
我预期的执行结果,控制台应该打印出 1,2,3
但是在执行的时候,程序却报错了
应该说是我的yield后面应该跟function但是上面的demo中我的yield后面跟的已经是function了为什么却没有预期的输出呢?
第二种写法:
const co = require(’co’);function are1(){}function are2(){}function are3(){}function* abc(){ var a = yield are1 console.log(1) var b = yield are2 console.log(2) var c = yield are3 console.log(3)}co(abc) .then(data =>{console.log(data) }) .catch(err =>{console.log(err) })
co已经接受一个generator的函数了,上面的这种写法也是没办法在控制台输出1,2,3的
问题解答
回答1:你的yield后面跟的不是are这个函数,而是are执行后的返回值。其实它等于yield undefined,这才是报错的原因。
回答2:function* are(){}回答3:
不支持普通函数
回答4:看看co库的源码就好,报错是co库报出来的,原因是因为楼上说的返回了undefined,具体报错代码如下:
if (value && isPromise(value)) return value.then(onFulfilled, onRejected);return onRejected(new TypeError(’You may only yield a function, promise, generator, array, or object, ’+ ’but the following object was passed: '’ + String(ret.value) + ’'’));
isPromise检测是否为Promise,co库先尝试将yield后转换为Promise,具体参见toPromise函数:
function toPromise(obj) { if (!obj) return obj; if (isPromise(obj)) return obj; if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); if (’function’ == typeof obj) return thunkToPromise.call(this, obj); if (Array.isArray(obj)) return arrayToPromise.call(this, obj); if (isObject(obj)) return objectToPromise.call(this, obj); return obj;}
传入的是undefined,所以最终toPromise返回了undefined,检测不是Promise,所以就抛出了错误。
至于为什么没有输出1,2,3的原因,是因为yield后面的关系,yield后面是要接受函数作为参数,并且要执行这个函数的,所以yield后面一般跟着的是异步操作,这个函数就是回调函数,但是的那个函数,所以这么改下就可以了:
function are1(fn) { fn();}function are2(fn) { fn();}function are3(fn) { fn();}