Почему этот генератор возвращает функцию вместо значения

По сути, я пытаюсь сделать http-запрос с моим приложением koa, и мне было интересно, что именно я буду делать неправильно.

var request = require('koa-request');
var beatsGen = beats();
var response1 = beatsGen.next().value;

function *beats (){
  var options = {
    url: 'https://api.github.com/repos/dionoid/koa-request',
    headers: { 'User-Agent': 'request' }
  };    
  var response = yield request(options);
}

Когда я консольно записываю ответ1, это то, что я получаю

respone from beats is function (callback) { 
        _request(uri, options, function (error, response, body) { 
            callback(error, response); 
        }) 
    }

Я подумал, что response1 будет объектом типа someType, содержащим параметр body обратного вызова, а не саму функцию. Итак, почему я получаю функцию как генераторы .next().value?

Я новичок в генераторах и коа, поэтому я предполагаю, что совершаю здесь глупую ошибку.


person Austin Davis    schedule 15.02.2015    source источник


Ответы (1)


koa-request или любая другая библиотека, которая возвращает thunks или promises/thenables для асинхронных вызовов, предназначена для использования с библиотекой сопрограмм, такой как co или с платформой веб-приложений koa, которая использует co для обработки потока управления на основе генератора.

Генераторы ECMAScript 6 не поддерживают асинхронность, но ECMAScript 7 будет иметь async и await чтобы справиться с этим изначально.

Заявление

var response1 = beatsGen.next().value;

возвращает значение, возвращенное первым оператором yield в долях, которое является переходом, возвращаемым request(options). Библиотека, поддерживающая сопрограммы, проверит возвращаемое значение из generator.next().value и дождется выполнения обратных вызовов или разрешения thenables, прежде чем возобновить работу тела генератора, снова вызвав generator.next().

Такой библиотекой является co:

var request = require('koa-request'),
    co = require('co');

function beats (){ //doesn't have to be a generator function
  var options = {
    url: 'https://api.github.com/repos/dionoid/koa-request',
    headers: { 'User-Agent': 'request' }
  };    
  return request(options); //return the thunk
}


co(function *() {
  var response1 = yield beats;
  //use response
})

Если это предназначено для использования с koa:

app.use(function *() {
  this.body = yield beats();
});

Кстати, koa-request лучше было бы назвать co-request, так как все обертки сопрограмм имеют префикс co-.

person c.P.u1    schedule 15.02.2015
comment
Спасибо чувак. На самом деле не осознавал какой-то лежащей в основе магии, которая происходила. Просто из любопытства, как бы вы порекомендовали модульное тестирование в koa. Я бы не смог запустить промежуточное ПО app.use просто из вызова функции .exports, что я и сделал с экспрессом на проходе. - person Austin Davis; 15.02.2015
comment
Вы можете использовать co-mocha для тестирования генераторов. - person c.P.u1; 15.02.2015