2014-12-23 2 views
5

저는 노드에 다소 익숙하지 않으며 완전히 koa에 익숙합니다. 생성기를 사용하여 비동기 웹 요청을 API에 보내려고하지만 모든 조각을 함께 모으는 방법을 알 수 없습니다.비동기 요청을 사용하여 yield를 사용하는 방법을 알아낼 수 없습니다.

필자는 블루 버드를 사용하고 있는데, 몇 가지 예를 보았 기 때문에 좋은 생각처럼 보였습니다. 블루 버드없이 원하는 것을 할 수있는 더 쉬운 방법이 있다면 그건 완전히 괜찮아요. 내 모듈에서

:

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; 
    }); 
}; 

을 내가 이런 식으로 전화 해요 :

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; 
}; 

내 콘솔에서 볼 때, 나는 참조 :

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

내가 아는 내 코드는 온통 일종이지만, 몇 시간 씩 작업 해 왔지만 아직 해결하지 못했습니다.

감사합니다.

답변

4

같은 것을 할 생각 : 그것은, 클러 애플리케이션 로직이, 거기에 속하지 않는 불필요 매우 매우 느립니다.

메서드를 coroutine으로 표시해야합니다. 그렇지 않으면 그냥 생성기입니다.

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; 
}); 

coroutines는 다른 coroutine과 함께 사용하거나 promise로 사용할 수있는 promise를 반환합니다. 당신은에 구축이다 koaco 라이브러리와 함께 작동하도록 같은 co-request 빌드로, 기존 request 래퍼 사용을 고려할 수

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

감사 무리 : KOA에서

당신이 뭔가를 할 것입니다! 그것은 매우 도움이되었고, 매력처럼 작동합니다. Promisify All 부분을 제안 된대로 init 파일로 옮겼습니다. – snollygolly

1

.then에서 발생기를 호출하는 것은 작동하지 않을 것입니다. 생성자를 호출하면 반복자 만 반환되고 아무 것도 수행하지 않습니다. 당신은 .then을 수행 할 필요가 없습니다

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; 
}; 

: 당신이 원하는 것은 (검증되지 않은) 같은 것입니다. 그것은 Koa의 직업입니다. 그것은 당신이 맺은 약속을 얻고, 해결 될 때까지 기다리고, 해결 된 값을 매개 변수로 iterator.next()으로 전달합니다.이 변수는 변수 result이되며, 그 함수는 다음 yield (또는 함수의 끝)으로 계속됩니다.

그러나 귀하의 경우 마지막 행에서 수행하는 것처럼 응답을 내고 싶지 않은 것은 분명합니다. 한 가지는 약속을해야하기 때문에 Koa 런타임 오류가 발생할 수 있습니다. 난 당신이 런타임 코드에 promisifyAll를 호출하지 마십시오 단지

this.body = response; 
0

: 이미 발전기를 사용하고 있기 때문에, 당신은뿐만 아니라 다른 코 루틴을 사용할 수 있습니다.

// 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); 
    } 

}); 
관련 문제