I'm somewhat new to node, and I'm pletely new to koa. I'm trying to use generators to do async web requests to an API, but I can't figure out how to put all the pieces together.
As a note, I'm using bluebird because I saw some examples do that, and it seemed like a good idea. If there's an easier way to do what I want without bluebird, that's totally fine as well.
In my module:
plugin.searchForItem = function * (name) {
Promise = require('bluebird');
request = Promise.promisifyAll(require('request'));
console.log("making request");
yield request.getAsync('').then(function * (result) {
var response = result[0];
var body = result[1];
console.log(response.statusCode);
yield response;
});
};
and I'm calling it like this:
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;
};
When I look in my console, I see:
search returned: [object Generator]
making request
search returned2: {"value":{"isFulfilled":false,"isRejected":false},"done":false}
search returned3: {"done":true}
I know my code is kind of all over the place, but I've worked on it for hours and I'm still no closer to fixing it.
Thanks!
I'm somewhat new to node, and I'm pletely new to koa. I'm trying to use generators to do async web requests to an API, but I can't figure out how to put all the pieces together.
As a note, I'm using bluebird because I saw some examples do that, and it seemed like a good idea. If there's an easier way to do what I want without bluebird, that's totally fine as well.
In my module:
plugin.searchForItem = function * (name) {
Promise = require('bluebird');
request = Promise.promisifyAll(require('request'));
console.log("making request");
yield request.getAsync('http://apisitegoeshere./apicall').then(function * (result) {
var response = result[0];
var body = result[1];
console.log(response.statusCode);
yield response;
});
};
and I'm calling it like this:
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;
};
When I look in my console, I see:
search returned: [object Generator]
making request
search returned2: {"value":{"isFulfilled":false,"isRejected":false},"done":false}
search returned3: {"done":true}
I know my code is kind of all over the place, but I've worked on it for hours and I'm still no closer to fixing it.
Thanks!
Share Improve this question asked Dec 23, 2014 at 16:11 snollygollysnollygolly 1,8862 gold badges17 silver badges32 bronze badges 03 Answers
Reset to default 4Please don't call promisifyAll
in runtime code: it's unnecessary, clutters application logic, doesn't belong there and is very very slow.
You need to mark the method as coroutine, otherwise it's just a 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.").get(0);
console.log(response.statusCode);
return response;
});
The coroutines returns a promise which you can consume with another coroutine or just use it as a promise. Since you are already using generators, you might as well use another coroutine:
search.searchForShow = Promise.coroutine(function* (name) {
var data = yield this.plugins[0].searchForItem(name);
console.log("search returned: " + data);
return data;
});
Calling a generator from .then
is not going to e close to working. Calling a generator merely returns its iterator and does nothing with it. What you want is something like (untested):
plugin.searchForItem = function * (name) {
Promise = require('bluebird');
request = Promise.promisifyAll(require('request'));
console.log("making request");
var result = yield request.getAsync('http://apisitegoeshere./apicall');
var response = result[0];
var body = result[1];
console.log(response.statusCode);
yield response;
};
You don't need to do the .then
. That is Koa's job. It will get the promise you yielded, wait for it resolve, pass back the resolved value as the parameter to iterator.next()
, which bees your variable result
, and the function will continue to the next yield
(or the end of the function).
However, in your case, it's not clear that you want to yield the response as you are doing in the last line. For one thing, you have to yield promises, so this will probably cause a Koa run-time error. I suspect you want something like just
this.body = response;
You might consider using an existing request wrapper, such as co-request build to work with the co library which koa is build upon.
In koa you would do something like:
// server.js
var request = require('co-request');
app.use(function *(){
try{
var result = yield request('http://apisitegoeshere./apicall');
this.body = result.body;
}
catch(err){
this.throw(500);
}
});
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744504204a4577608.html
评论列表(0条)