2014-12-23 7 views
5

Jestem trochę nowy w węźle, a ja jestem zupełnie nowy w koa. Próbuję użyć generatorów do asynchronizowania żądań internetowych z interfejsem API, ale nie mogę wymyślić, jak połączyć wszystkie elementy.Nie mogę wymyślić, jak wykorzystać wydajność z prośbą asynchroniczną

Na marginesie, używam bluebirda, ponieważ widziałem kilka przykładów, i to wyglądało na dobry pomysł. Jeśli jest łatwiejszy sposób na zrobienie tego, co chcę bez bluebirda, to też jest w porządku.

W moim module:

plugin.searchForItem = function * (name) { 
    Promise = require('bluebird'); 
    request = Promise.promisifyAll(require('request')); 
    console.log("making request"); 
    yield request.getAsync('http://apisitegoeshere.com/apicall').then(function * (result) { 
    var response = result[0]; 
    var body = result[1]; 
    console.log(response.statusCode); 
    yield response; 
    }); 
}; 

i dzwonię to tak:

search.searchForShow = function (name) { 
    data = this.plugins[0].searchForItem(name); 
    console.log("search returned: " + data); 
    console.log("search returned2: " + JSON.stringify(data.next())); 
    console.log("search returned3: " + JSON.stringify(data.next())); 
    return data; 
}; 

Kiedy patrzę w mojej konsoli, widzę:

search returned: [object Generator] 
making request 
search returned2: {"value":{"isFulfilled":false,"isRejected":false},"done":false} 
search returned3: {"done":true} 

wiem mój kod jest wszędzie, ale pracowałem nad nim przez wiele godzin i nadal nie jestem bliżej do naprawienia tego.

Dzięki!

Odpowiedz

4

proszę nie dzwonić promisifyAll w kodzie wykonawczego: to niepotrzebne, logika aplikacji zaśmiecanie, nie należą tam i jest bardzo powolny.

Należy oznaczyć metodę jako coroutine, w przeciwnym razie jest to tylko generator.

var Promise = require("bluebird"); 
// Assumes request is promisified else where, like in your init file 
var request = require("request"); 

plugin.searchForItem = Promise.coroutine(function* (name) { 
    var response = yield request.getAsync("http://www.google.com").get(0); 
    console.log(response.statusCode); 
    return response; 
}); 

W współprogram zwraca obietnicę, które można spożywać z innym współprogram lub po prostu użyć go jako obietnicę. Skoro już używasz generatory, równie dobrze można użyć innego współprogram:

search.searchForShow = Promise.coroutine(function* (name) { 
    var data = yield this.plugins[0].searchForItem(name); 
    console.log("search returned: " + data); 
    return data; 
}); 
+0

Dzięki kilka! To było bardzo pomocne i działa jak urok. Przeniosłem moją promisifyAll część do pliku init zgodnie z sugestią. – snollygolly

1

Wywołanie generatora z .then nie będzie bliskie pracy. Wywołanie generatora po prostu zwraca jego iterator i nic z nim nie robi. Co chcesz to coś (niesprawdzone):

plugin.searchForItem = function * (name) { 
    Promise = require('bluebird'); 
    request = Promise.promisifyAll(require('request')); 
    console.log("making request"); 
    var result = yield request.getAsync('http://apisitegoeshere.com/apicall'); 
    var response = result[0]; 
    var body = result[1]; 
    console.log(response.statusCode); 
    yield response; 
}; 

Nie trzeba robić .then. To jest praca Koa. Otrzyma on obietnicę, którą ustąpiłeś, zaczekasz na jej rozwiązanie, przekazuje rozstrzygniętą wartość jako parametr do iterator.next(), która staje się zmienną result, a funkcja będzie kontynuowana do następnego yield (lub do końca funkcji).

Jednak w twoim przypadku nie jest jasne, czy chcesz uzyskać odpowiedź tak, jak robisz w ostatnim wierszu. Po pierwsze, musisz składać obietnice, więc prawdopodobnie spowoduje to błąd czasu Koa. Podejrzewam, że chcesz coś podobnego tylko

this.body = response; 
0

Można rozważyć przy użyciu istniejącego request opakowanie, takie jak co-request budowie pracować z biblioteką co który koa jest opierać.

W KOA byś zrobił coś takiego:

// server.js 
var request = require('co-request'); 

app.use(function *(){ 
    try{ 
     var result = yield request('http://apisitegoeshere.com/apicall');  
     this.body = result.body; 
    } 
    catch(err){ 
     this.throw(500); 
    } 

}); 
Powiązane problemy