Ответ 1
Да, начиная с версии 0.11. Наслаждайтесь!
http://wingolog.org/archives/2013/05/08/generators-in-v8
http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
Есть ли способ получить 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 могло бы помочь?
Да, начиная с версии 0.11. Наслаждайтесь!
http://wingolog.org/archives/2013/05/08/generators-in-v8
http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
Ответ "сейчас нет", но Марсель, похоже, мой герой. Надеюсь, что это куда-то:
https://groups.google.com/forum/#!msg/nodejs/BNs3OsDYsYw/oCsWBw9AWC0J https://github.com/laverdet/node-fibers
Вы можете использовать генераторы в 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.
По-видимому, не в текущей стабильной версии. Тем не менее, вы можете добиться того же, используя 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);
}
});
Вы можете проверить wu.js на http://fitzgen.github.com/wu.js/ В нем много интересных функций итератора.
Да и нет.
var myGen = (function () {
var i = 0;
return function () {
i++; return i; }
})();
var i;
while ((i = myGen()) < 100 ) {
do something; }
Как вы видите, вы можете реализовать что-то вроде использования с закрытием, но у него нет встроенных генераторов.
issue предложение генераторов в v8 недавно было принято участником проекта v8.
Пожалуйста, проголосуйте, чтобы сделать yield
выполнимым.
Обновление 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
})
Мы используем gnode
для генераторов в node < 0.11.3 - https://github.com/TooTallNate/gnode