Utilizing Bluebird to Promisfy Mongoose, I have a Promise.map(function with a series of if/else for looping through an array to see if a reference doc exists, else create one..
Assigning the product of findOneAsync to a variable, to then assign 'variable._id' to a new doc in the making (the main promise), the console logs {"isFulfilled":false,"isRejected":false}
Here's a snippet:
for (i=0; i<items.length; i++) {
var existingItem = Models.Items.findOneAsync({ item: items[i] });
console.log( "existingItem : ");
console.log( JSON.stringify(existingItem) );
console.log( "existingItem._id : " + existingItem._id );
Here's a log:
existingItem :
{"isFulfilled":false,"isRejected":false}
existingItem._id : undefined
Why might the existingItem
variable be pending for the Model.Item.findOneAsync..?
Utilizing Bluebird to Promisfy Mongoose, I have a Promise.map(function with a series of if/else for looping through an array to see if a reference doc exists, else create one..
Assigning the product of findOneAsync to a variable, to then assign 'variable._id' to a new doc in the making (the main promise), the console logs {"isFulfilled":false,"isRejected":false}
Here's a snippet:
for (i=0; i<items.length; i++) {
var existingItem = Models.Items.findOneAsync({ item: items[i] });
console.log( "existingItem : ");
console.log( JSON.stringify(existingItem) );
console.log( "existingItem._id : " + existingItem._id );
Here's a log:
existingItem :
{"isFulfilled":false,"isRejected":false}
existingItem._id : undefined
Why might the existingItem
variable be pending for the Model.Item.findOneAsync..?
-
I don't see you assigning a value to
variable._id
. Are we supposed to imagine what your code looks like? – JLRishe Commented Feb 12, 2015 at 6:03
5 Answers
Reset to default 9Your question is not really clear, but my question to you would be: why would existingItem
not be pending right after you retrieved it?
Do you understand how to use promises? Most of the time you need to get at their resolved values using .then()
or other promise manipulation functions:
var existingItem = Models.Items.findOneAsync({ item: items[i] });
existingItem.then(function (value) {
console.log( "existingItem : ");
console.log( JSON.stringify(existingItem) );
console.log( JSON.stringify(value); );
console.log( "existingItem._id : " + existingItem._id );
});
You need to wait until the promise gets resolved (or rejected). You can use any one of the following two ways:
1. By 'awaiting' to get the final state of the promise as follows:
var existingItem = await Models.Items.findOneAsync({ item: items[i] });
2. By handling the promise using '.then' handler as follows:
return Models.Items.findOneAsync({ item: items[i] })
.then(function(existingItem) {
console.log("existingItem", existingItem);
I think you want:
return Promise.each(items, function(item) {
return Models.Items.findOneAsync({item: item}).then(function(existingItem) {
console.log("existingItem", existingItem);
});
});
findOneAsync() simply hasn't finished running yet when you start writing the console.logs.
Also plicating things, it looks like findOneAsync()
is returning a Promise (status is neither fulfilled nor rejected yet at the point you are writing logs).
So if you want to store and log the found item, you need to
- Wait for the Promise to resolve by using its
.then()
fucntion, and - Retrieve the found item from the "resolved value".
findOneAsync()
should pass the found item object as a parameter to itsresolve()
function (i.e. somewhere insidefindOneAsync()
there would be:resolve(foundItem);
).
Assuming all that, this should work:
for (i=0; i<items.length; i++) {
var findPromise = Models.Items.findOneAsync({ item: items[i] });
//the next line won't run until findOneAsync finishes
findPromise.then(resolveResult => {
var existingItem = resolveResult;
console.log( "existingItem : ");
console.log( JSON.stringify(existingItem) );
console.log( "existingItem._id : " + existingItem._id );
}
}
The root cause is, your are not waiting until the operation is finished. You are logging before findOne
operation is finished.
You can use either then
or await
to wait until the operation finishes.
then
Item.findOne({ where: { id: your_id } }) .then(result => console.log(result))
await
function must be prefixed withasync
key, but this code is much cleanerconst result = await Item.findOne({ where: { id: your_id } }) console.log(result)