Reputation: 7950
I'm new to nodejs and struggling with its asynchronous behaviour.
What I want to do is writing an REST API, which will consumes other APIs and is dependent on these results.
What I tried to do is capsuling the calls into functions [1] and collect the data and do something with it [2] before I send it to the caller of my API.
The problem is that at the time I'm collecting [2] the data, the callApiX
functions [1] are still running which will end up in undefined
values. Also, I need to call some of the functions more than 1 time and compare the values.
[1] Functions to call APIs:
function callApi1() {
var result =
{
"code": "",
"name": "",
"lat": 0,
"lng": 0
};
var request = require("request");
var url = "someurl";
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
// fill result
result.code = body.code; // etc.
// the correct result is being displayed
console.log(result);
return result;
}
})
}
function callApi2() // ...
[2] get Data from functions and add to request
var express = require('express');
var router = express.Router();
app.route('/api')
.get(function(req, res) {
// array for results
var results = [];
// all this data is going to be undefined, since the callApiX functions [1] are still running
results += callApi1();
results += callApi2();
results += callApi3();
// do something with the data collected in results before being sent back to the caller of my API
res.json(results); // output: {undefinedundefinedundefined}
});
How could I possibly solve this?
Upvotes: 0
Views: 65
Reputation: 77482
There are several ways (nested callbacks, promises ... ) how you can achieve what you want, one of them you can see below
Example how you can solve this problem with use async,
npm install async
JS:
var async = require('async');
function callApi1 (callback) {
var result =
{
"code": "",
"name": "",
"lat": 0,
"lng": 0
};
var request = require("request");
var url = "someurl";
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
result.code = body.code;
return callback(null, result)
} else {
callback(error);
}
})
}
function callApi2() // ...
var express = require('express');
var router = express.Router();
app.route('/api')
.get(function(req, res) {
async.parallel([
function(callback){
callApi1(callback);
},
function(callback) {
callApi2(callback);
},
function(callback){
callApi3(callback);
}
], function (err, results) {
res.json(results);
});
});
What function parallel do, from doc
Run the tasks array of functions in parallel, without waiting until the previous function has completed. If any of the functions pass an error to its callback, the main callback is immediately called with the value of the error. Once the tasks have completed, the results are passed to the final callback as an array.
Upvotes: 1