【问题标题】:Generator function with name带名称的生成器函数
【发布时间】:2016-12-15 19:12:10
【问题描述】:

我刚刚开始使用 Bluebird 的 Promise.coroutine,它是 ES6 中 Generator functions 的承诺版本。

当我创建一个函数并将其放入变量时,一切正常。喜欢:

let success = Promise.coroutine(function* (_context) {
    ...
});

exports.success = Promise.coroutine(function* (_context) {
    ...
});

但是当我尝试创建一个独立的函数时。喜欢:

Promise.coroutine(function *success() {
    ...
});

它从不定义函数,我得到错误:

成功没有定义

如何访问独立的生成器函数?或者更直接,如何创建它?

编辑:

我正在使用 validatejs,它需要异步验证的成功和错误函数:

exports.create = function (req, res) {

    var constraints = {
        ...
    }

    validate.async(req, constraints).then(Promise.coroutine(success), Promise.coroutine(error));

    function success() {    //generator
    }

    function error(e) {     //generator
    }
}

【问题讨论】:

  • 你能显示错误是在哪里引发的吗?你在哪里尝试访问success
  • 那是错误,实际上success 从未定义过。所以在 JS 中调用未定义的对象是一个错误。现在按照Agalo 的建议解决了。
  • 但是你仍然错过了你尝试使用success的部分。显示的错误会导致您在问题中未显示的部分代码。
  • 我已经添加了必须传递函数的行。
  • 函数的名称,无论是否生成器,都只能从函数内部访问,如果该函数直接用作参数。对于foo(function bar() {})bar 也只能从bar 函数本身中访问。 var foo = { bar : function bar() {}}; 也是如此

标签: javascript node.js ecmascript-6 bluebird


【解决方案1】:

您可以定义如下所示的生成器函数。

function* functionName([param[, param[, ... param]]]) {
   statements..
}

请注意,符号 * 带有 function 字样,而不是函数名。声明函数关键字后跟星号定义生成器函数。

Update1:​​ 使用 Promise.coroutine 方法。在 javascript 中,函数是一等公民,因此可以作为参数传递。因此,您可以将函数表达式替换为函数名。

Promise.coroutine(functionName);

【讨论】:

  • 以及如何将其包装在协程中?
  • 我没有使用过 Bluebird 的 Promise.coroutine。但是,我相信你可以将它作为函数参数传递,因为它期望函数作为参数。
  • @t.niese 是的,你是对的。他写的不正确但解释正确:)
  • 我认为这并不完全正确。问题是您试图调用 success() 但这并没有在您的上下文(或实际范围)中真正定义。
  • @migueldiab 是的,您可以参考问题以了解我定义的位置和调用位置的详细信息。
【解决方案2】:

您的success() 函数不必命名,因为您实际上不是调用它,而是调用协程 Promise。请参见下面的示例。您应该将您的协程分配给您尝试从中调用它的任何内容,然后为您的延迟处理(无论可能是什么)产生一个 Promise。然后你需要调用协程来处理返回承诺。

var Promise = require("bluebird");

function Test() {

}

Test.prototype.foo = Promise.coroutine(function* success() {
  console.log("Called success")
  var i = 0;

  while (i < 3) {
    console.log("Waiting and Yield " + i++);
    yield Promise.delay(1000);
  }
  console.log("Test " + i);
});


var a = new Test();
a.foo();
console.log("Done!");

然后你会得到这个输出:

>node index.js
Called success
Waiting and Yield 0
Done!
Waiting and Yield 1
Waiting and Yield 2
Test 3

【讨论】:

  • 我在需要它的地方做同样的事情,但我有一个稍微不同的场景在问题中解释我不想创建一个新变量来保存我的功能。
猜你喜欢
  • 1970-01-01
  • 2014-10-16
  • 2014-02-12
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 2010-11-18
  • 2021-01-16
相关资源
最近更新 更多