Reputation: 2084
My promise-then chain does not appear to wait for each previous return statement.
new Promise(function (resolve, reject) {
console.log("1");
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("2");
if (info.item) {
console.log("item exists, don't retry");
return (info);
}
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
return(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("3");
const http = require('http');
http.get('otherurl' + info.item, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
console.log("processed");
return (info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("4 " + info);
});
I want my output to be, eg.:
1
2
3
processed
4 [someinfo]
Here is what I get:
1
2
3
4 undefined
processed
It appears that only the first promise-then happen asynchronously. Why aren't the second and third then statements waiting for the prior return?
Upvotes: 0
Views: 55
Reputation: 66
You are only resolving your first promise. When you return a value inside a callback you are not resolving the promise. You need to use the same strategy you use for the first one, wrapping the callback on a promise. So in your steps 2 and 3 you should return a new Promise and resolve it in the callback.
(...)
.then(function(result){
return new Promise(function(resolve, reject){
someThingWithCallback(result, function(err, data){
resolve(data)
})
})
})
.then(function(data){
...
})
You should try to avoid using a module that uses callbacks if you want to work with promises. You can use something like request-promise or axios.
Upvotes: 1
Reputation: 12552
The code currently is:
new Promise(function (resolve, reject) {
console.log("1");
return(http.ClientRequest)
}).then(function (info) {
console.log("2");
return(http.ClientRequest)
}).then(function (info) {
console.log("3");
resolve(http.ClientRequest)
}).then(function (info) {
console.log("4 " + info);
});
To work a Promise chain needs to return
a promise from the then
part. But anything you return
from then
is treated as promise. But in your case
return http.get(...)
you will get http.ClientRequest
object in your next then chain. Not the actual data.So in your case a crude way to do this will be: Promisifying each http
call.
new Promise(function (resolve, reject) {
console.log("1");
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}).then(function (info) {
console.log("2");
if (info.item) {
console.log("item exists, don't retry");
return (info);
}
return new Promise(function (resolve, reject) {
const http = require('http');
http.get(url, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
var info;
// process data
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
})
}).then(function (info) {
console.log("3");
return new Promise(function (resolve, reject) {
const http = require('http');
http.get('otherurl' + info.item, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
console.log("processed");
resolve(info);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
})
}).then(function (info) {
console.log("4 " + info);
});
Note: As I said it is a very non-elegant way of doing things, I would suggest using a promise based library like axios
or maybe use async
library instead of promises. Also you can use async-await
. Each of them are better approach.
Upvotes: 2