Unable to figure out how to use output with asynchronous request

I am a little new to node and I am completely new to koa. I am trying to use generators to create asynchronous web requests in an API, but I cannot figure out how to assemble all the parts.

As a note, I use bluebird because I saw some examples, and that seemed like a good idea. If there is an easier way to do what I want without a bluebird, that's fine too.

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

and I call 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 at 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 that my code is everything, but I worked on it for several hours, and I'm still not closer to fixing it.

Thanks!

+5
source share
3 answers

Please do not call promisifyAll at runtime: it is not needed, the application logic is cluttered, it does not exist there and it is very slow.

You need to mark the method as a coroutine, otherwise it is 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.com").get(0); console.log(response.statusCode); return response; }); 

A promise is returned in the coroutine, which you can use with another coroutine or just use it as a promise. Since you already use generators, you can use another coroutine:

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

Calling a generator from .then not suitable for operation. A generator call simply 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.com/apicall'); var response = result[0]; var body = result[1]; console.log(response.statusCode); yield response; }; 

You do not need to do .then . This is the work of Koa. It will receive the promise you made, wait for its resolution, pass the allowed value as the iterator.next() parameter, which will become your result variable, and the function will continue the next yield (or end of the function).

However, in your case it is not clear what you want to give the answer, as you do in the last line. First, you should get promises, so this is likely to cause a Koa runtime error. I suspect you want something like just

 this.body = response; 
+1
source

You can use an existing request shell, such as co-request, to work with the co library, which is koa .

In koa, you would do something like:

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

Source: https://habr.com/ru/post/1209781/


All Articles