问题
Context: A device is sending me data at regular interval. When I receive those data I have to process them and store them in a database. We use Node.js 6.11.0, and the library node-postgres to query the database.
We store those data, then we do a bunch of operation on them. Since we have to wait for the database to finish storing them, we rely on ES6 promise.
Here's a sample of the code.
First, the part of the code where we are getting the data
processData(data).then(result => {
doSomethingElse(result)
}).catch(error => console.log(error));
processData() which is the function where we store the data in the database.
function processData(data){
return new Promise((resolve,reject)) => {
pg.query('select query',[parameters],(err,res) => {
if(err) {
reject('something went wrong');
} else {
// Do a bunch of stuff
pg.query('insert data query',[parameters2],(er,rs) => {
if(er){
reject("Unable to save data");
}else {
console.log("Data Stored");
try{
//An object containing the result and other stuff
let results = {a:rs.rows[0],b:'...',c:'....'};
if(results.a.key){
//Do a bunch of other stuff for this type of data
// involving promises and resolving
} else{
resolve(results);
}
}catch(exception) {
reject(exception);
}
})
}
});
});
}
This function treat two type of data : One with which we do a bunch of other operation before resolving, and another one we resolve directly. We store both in the database, and to differentiate them we use the value of result.a.key which wouldn't be "null" for the first type.
Since the problem only concern the second type (the one we resolve directly), I did not think it was useful to specify the code inside the if.
Finally, the doSomethingElse() function
function doSomethingElse(result) {
//Only do something if those key exist
if(result.b.foo && result.b.bar) {
console.log('We are doing some other stuff');
//Do Something Else
}
}
Problem :
Sometimes, in 10% of case, the promise is neither rejecting or resolving.
- It does not resolve, because it does not show the message "We are doing some other stuff" from doSomethingElse() (it should be cause result.b.foo && result.b.bar will always be the same value for two data from a same device).
- It does not reject because we do no get any kind of error in the catch
- It's random, for two data that are similar in everyway, sometimes it works and sometimes it does not.
- It is getting saved in the database because we are getting the "Data Stored" message.
- For the first type of data, it never does it.
As a band-aid solution, we put the doSomethingElse() function above the resolve, and refactored the code to go with it. And...it works. It works 100% of the time.
I have no idea what is going one, maybe I am not understanding something about Promise, because I don't see any major differences with what we were doing beforehand.
Do you have any idea of what is going on, and how this might happened ? How could I fix that ?
Thanks you
来源:https://stackoverflow.com/questions/49728901/es6-promise-are-sometimes-not-resolving