IsGenerator 实现
IsGenerator implementation
我之前依赖于以下如何检测生成器的定义:
function isGenerator(func) {
return func instanceof Function && func.constructor.name === 'GeneratorFunction';
}
从那时起,我遇到了各种其他验证,包括检查原型上的 next
和 throw
函数。
有没有办法在 NodeJS 0.10 的范围内实现 isGenerator
功能被认为是全面的 - 5.x?
我打算在其中使用的应用程序是选择任何生成器(甚至迭代器),并将其包装成一个使用函数 next
和 throw
的承诺。
为此,我使用了来自 here:
的修改示例
/////////////////////////////////
// Generator-to-Promise adapter;
function asyncAdapter(generator) {
return function () {
var g = generator.apply(this, arguments);
function handle(result) {
if (result.done) {
return Promise.resolve(result.value);
}
return Promise.resolve(result.value)
.then(function (res) {
return handle(g.next(res));
}, function (err) {
return handle(g.throw(err));
});
}
return handle(g.next());
}
}
I previously relied on the following definition of how to detect a generator […]
它不检测生成器,它检测生成器函数。而且你不应该 依赖 这样的东西,因为每个函数都可以 return 生成器。
Is there a way to implement isGeneratorFunction
to be considered comprehensive within the realm of NodeJS 0.10 - 5.x?
是的,有 are a few,在您展示的 .constructor.name
方法旁边,也可以使用 instanceof
或 .toString()
。
The application in which I intend to use is to pick up any generator (or even iterator)
不要变魔术。只需让用户决定他们是否要使用生成器,并让他们在这种情况下显式调用您的函数。
ES 6 说
9.2.6 GeneratorFunctionCreate (kind, ParameterList, Body, Scope, Strict)
The abstract operation GeneratorFunctionCreate requires the arguments: kind which is one of (Normal, Method), a parameter list production specified by ParameterList, a body production specified by Body, a Lexical Environment specified by Scope, and a Boolean flag Strict.
GeneratorFunctionCreate performs the following steps:
- Let functionPrototype be the intrinsic object %Generator%.
- Let F be FunctionAllocate(functionPrototype, Strict,
"generator"
).
- Return FunctionInitialize(F, kind, ParameterList, Body, Scope).
所以你可以通过检查原型来接近
是否适合发电机。 Object.getPrototypeOf
让我们测试 functionPrototype 的值是否是内置的 %Generator% 尽管代理对象可以控制 Object.getPrototypeOf
的结果。将生成器的代理视为生成器可能是一件好事。
function isGenerator(functionThatMightBeGenerator) {
function *nullGenerator() {}
return (functionThatMightBeGenerator
&& Object.getPrototypeOf(functionThatMightBeGenerator)
=== Object.getPrototypeOf(nullGenerator));
}
如果您担心区分生成器代理和生成器,您可以查看 14.5.14#6.g.i。这要求 class 声明禁止生成器作为超类型,因此可以直接检查 FunctionKind 内部插槽是否为 "generator"
.
这可能有点矫枉过正,但类似于
function isGeneratorAndProbablyNotProxyThereof(functionThatMightBeGenerator) {
function *nullGenerator() {}
if (!functionThatMightBeGenerator
|| (Object.getPrototypeOf(functionThatMightBeGenerator)
!== Object.getPrototypeOf(nullGenerator))) {
return false;
}
function defineAndThrowawaySubClass(superType) {
class C extends superType {}
}
let isGenerator = false;
try {
defineAndThrowawaySubClass(functionThatMightBeGenerator);
} catch (e) {
isGenerator = e instanceof TypeError;
}
return isGenerator;
}
应该这样做,尽管有足够动机的代理作者也可能会欺骗它。
我之前依赖于以下如何检测生成器的定义:
function isGenerator(func) {
return func instanceof Function && func.constructor.name === 'GeneratorFunction';
}
从那时起,我遇到了各种其他验证,包括检查原型上的 next
和 throw
函数。
有没有办法在 NodeJS 0.10 的范围内实现 isGenerator
功能被认为是全面的 - 5.x?
我打算在其中使用的应用程序是选择任何生成器(甚至迭代器),并将其包装成一个使用函数 next
和 throw
的承诺。
为此,我使用了来自 here:
的修改示例/////////////////////////////////
// Generator-to-Promise adapter;
function asyncAdapter(generator) {
return function () {
var g = generator.apply(this, arguments);
function handle(result) {
if (result.done) {
return Promise.resolve(result.value);
}
return Promise.resolve(result.value)
.then(function (res) {
return handle(g.next(res));
}, function (err) {
return handle(g.throw(err));
});
}
return handle(g.next());
}
}
I previously relied on the following definition of how to detect a generator […]
它不检测生成器,它检测生成器函数。而且你不应该 依赖 这样的东西,因为每个函数都可以 return 生成器。
Is there a way to implement
isGeneratorFunction
to be considered comprehensive within the realm of NodeJS 0.10 - 5.x?
是的,有 are a few,在您展示的 .constructor.name
方法旁边,也可以使用 instanceof
或 .toString()
。
The application in which I intend to use is to pick up any generator (or even iterator)
不要变魔术。只需让用户决定他们是否要使用生成器,并让他们在这种情况下显式调用您的函数。
ES 6 说
9.2.6 GeneratorFunctionCreate (kind, ParameterList, Body, Scope, Strict)
The abstract operation GeneratorFunctionCreate requires the arguments: kind which is one of (Normal, Method), a parameter list production specified by ParameterList, a body production specified by Body, a Lexical Environment specified by Scope, and a Boolean flag Strict.
GeneratorFunctionCreate performs the following steps:
- Let functionPrototype be the intrinsic object %Generator%.
- Let F be FunctionAllocate(functionPrototype, Strict,
"generator"
).- Return FunctionInitialize(F, kind, ParameterList, Body, Scope).
所以你可以通过检查原型来接近
是否适合发电机。 Object.getPrototypeOf
让我们测试 functionPrototype 的值是否是内置的 %Generator% 尽管代理对象可以控制 Object.getPrototypeOf
的结果。将生成器的代理视为生成器可能是一件好事。
function isGenerator(functionThatMightBeGenerator) {
function *nullGenerator() {}
return (functionThatMightBeGenerator
&& Object.getPrototypeOf(functionThatMightBeGenerator)
=== Object.getPrototypeOf(nullGenerator));
}
如果您担心区分生成器代理和生成器,您可以查看 14.5.14#6.g.i。这要求 class 声明禁止生成器作为超类型,因此可以直接检查 FunctionKind 内部插槽是否为 "generator"
.
这可能有点矫枉过正,但类似于
function isGeneratorAndProbablyNotProxyThereof(functionThatMightBeGenerator) {
function *nullGenerator() {}
if (!functionThatMightBeGenerator
|| (Object.getPrototypeOf(functionThatMightBeGenerator)
!== Object.getPrototypeOf(nullGenerator))) {
return false;
}
function defineAndThrowawaySubClass(superType) {
class C extends superType {}
}
let isGenerator = false;
try {
defineAndThrowawaySubClass(functionThatMightBeGenerator);
} catch (e) {
isGenerator = e instanceof TypeError;
}
return isGenerator;
}
应该这样做,尽管有足够动机的代理作者也可能会欺骗它。