Получает ли поддержка node.js?

Есть ли способ получить generators в node.js?

В настоящее время я обманываю их обратными вызовами, но я должен не забыть проверить ответ обратного вызова внутри моей функции генератора, который создает много if (callback(arg) === false) return;

Мне нужно что-то вроде python:

for p in primes():
  if p > 100: break
  do_something(p)

который я делаю в node следующим образом:

primes(function(p) {
  if (p > 100) return false;
  do_something(p)
});

Возможно, что-то вроде coffeescript могло бы помочь?

Ответ 3

Вы можете использовать генераторы в Node.js, но только в 0.11+. Node.js 0.12 (стабильный) теперь доступен. Добавьте --harmony_generators или --harmony в параметры командной строки node, чтобы включить его.

С Traceur вы можете скомпилировать JavaScript на JavaScript. Вы можете сделать загрузчик для Node.js, который делает это на лету. Поскольку он работает и компилируется на ванильный JavaScript, он запускается в Node.js < 0.11, а также в браузере.

Facebook разработал более легкую версию, которая поддерживает только генераторы, называемые Regenerator. Он работает аналогично Traceur.

Ответ 4

По-видимому, не в текущей стабильной версии. Тем не менее, вы можете добиться того же, используя node -fibers + promises.

Вот моя реализация:

var fiber = require('fibers');

module.exports.yield = function (promise) {

    var currentFiber = fiber.current;
    promise
        .then(function (value) {
            currentFiber.run(value);
        })
        .otherwise(function (reason) {
            currentFiber.throwInto(reason);
        });

    return fiber.yield();
};
module.exports.spawn = function (makeGenerator) {
    fiber(function () {
        makeGenerator.apply(this, Array.prototype.slice.call(arguments, 1));
    }).run();
};

И пример кода о том, как он работает: (query.find возвращает обещание)

        var generators = require('./utils/generators');
        var query = require('./utils/query');

        generators.spawn(function () {
            try {
                var field1 = generators.yield(query.find('user', { _id : '1' }));
                var field2 = generators.yield(query.find('user', { _id : '2' }));
                console.log('success', field1[0]._id, field2[0]._id);
            }
            catch (e) {
                console.error('error', e);
            }
        });

Ответ 5

Вы можете проверить wu.js на http://fitzgen.github.com/wu.js/ В нем много интересных функций итератора.

Ответ 6

Да и нет.

var myGen = (function () {
    var i = 0;
    return function () {
        i++; return i; }
})();
var i;
while ((i = myGen()) < 100 ) {
    do something; }

Как вы видите, вы можете реализовать что-то вроде использования с закрытием, но у него нет встроенных генераторов.

Ответ 7

issue предложение генераторов в v8 недавно было принято участником проекта v8.
Пожалуйста, проголосуйте, чтобы сделать yield выполнимым.

Ответ 8

Обновление 2014: Node теперь поддерживает обратные вызовы. Ниже приводится сообщение от 2010 года.


Вы должны использовать обратные вызовы. Если функция делает что-то асинхронно, вам также может понадобиться обратный вызов продолжения (продолжение является плохим словом, поскольку оно также означает что-то другое, но вы получаете мою точку.)

primes(function(p) {
  if (p > 100) return false // i assume this stops the yielding
  do_something(p)
  return true // it also better to be consistent
}, function(err) { // fire when the yield callback returns false
  if (err) throw err // error from whatever asynch thing you did
  // continue...
})

Обновлен с помощью кода примера

Я перевернул его, так что он возвращает true при завершении (так как null, false и undefined все равно будут равно false).

function primes(callback) {
  var n = 1, a = true;
  search: while (a)  {
    n += 1;
    for (var i = 2; i <= Math.sqrt(n); i += 1)
      if (n % i == 0)
        continue search;
    if (callback(n)) return
  }
}

primes(function(p) {
  console.log(p)
  if (p > 100) return true
})