2015-01-13 2 views
0

Используя koa.js, я хочу создать API, который запускает функцию генератора, которая длится много времени в фоновом режиме, но сразу же отправляет токен пользователю.ES6 Koa.js запускает функцию генератора для завершения и возвращает асинхронно

Пользователь может затем использовать этот токен для получения статуса своей работы позже.

'use strict'; 
var generateToken = function(){ 
    //... 
}; 

var processData = function *(data, token) { 
    //... 
    var a = yield analysis(data); 
    console.log(a) // a is undefined 
}; 

app.post('/process_data', validate, function *(next) { 
    var token = generateToken(); 
    var that = this; 
    setTimeout(function() { 
     for (var i of processData(that.request.body, token)){ 
      continue; 
     } 
    }); 
    this.body = "this should return immediately " + token; 
    return next; 
}); 

Выполнение этой задачи в рамках setTimeout, переменная 'a' не сохраняется. Как это сделать, чтобы processData выполнялся точно так же, как и нормальный доход?

+0

Я думаю, что вы захотите использовать [co] (https://github.com/tj/co) напрямую – Bergi

+0

Вы правы. благодаря! –

ответ

0

Благодаря Берги для решения.

app.post('/process_data', validate, function *(next) { 
    var token = generateToken(); 

    co(processData(this.request.body, token)); 

    this.body = "this should return immediately " + token; 
    return next; 
}); 
+0

Afaik вы можете упростить 'co (processData (this.request.body, токен))'. Нет необходимости в выражении анонимного генератора. – Bergi

+0

yep, он работает. еще раз спасибо. –

2

Вы, вероятно, хотите иметь длительный процесс работает получить обрабатываются очереди заданий, таких как Kue

Вы бы очередь работу с HTTP Post

затем проверить на работу с HTTP GET

Вот грубый набросок того, что я думаю, что вы хотите делать:

var kue  = require('kue'), 
    koa  = require('koa'), 
    route  = require('koa-router'), 
    thunkify = require('thunkify'), 
    parse  = require('co-body'), 
    co  = require('co'), 
    app  = koa(), 
    jobs  = kue.createQueue(); 

app.use(route(app)); 

// turn callbacks into thunks for generators 
var createJob = thunkify(jobs.create); 
var findJob = thunkify(kue.Job.get); 

// Process the job here 
jobs.process('longProcess', function(job, done){ 
    // do work in here 
    // call done(err) when completed 
    // EDIT: if you want to handle job using generators/yield 
    // you could use a library like co 
    co(function *(){ 
     var qs = yield doWork(job.data); 
     done(); 
     }).error(done); 
}); 

// Queue/Start the Job here 
app.post('/jobs', function *(){ 
    var body = yield parse(this); 
    var job = yield createJob('longProcess', body); 
    this.body = job.id; 
}); 

// Check Status of job here 
app.get('/jobs/:token', function *(){ 
    var job = yield findJob(this.params.token); 
    this.body = job; 
    // job.status === 'complete' || ... 
}); 

app.listen(3000); 
+0

Что делать, если вы хотите уступить другому процессу в обратном вызове jobs.process? Как бы вы это сделали? –

+0

Вы имеете в виду использование генератора/выхода и т. Д.? –

+0

Да, как я могу получить генератор, а затем отправить обратно результат возврата генератора, например: 'var jobs = kue.createQueue(); jobs.process (функция 'вопросы', (работа, сделано) { вар генераторных = вопросы (job.data); вар а = gen.next(); job.send (а); сделано() ; }); функция * вопросы (данные) { var qs = yield * processQuestions (data); } ' Где processQuestions - еще один генератор –