最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Promise findOneAsync variable = {"isFulfilled":false,"isRejected":false}? - Sta

programmeradmin6浏览0评论

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..?

Share Improve this question edited Feb 12, 2015 at 4:05 Stacks asked Feb 12, 2015 at 3:34 StacksStacks 3693 gold badges6 silver badges19 bronze badges 1
  • 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
Add a ment  | 

5 Answers 5

Reset to default 9

Your 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

  1. Wait for the Promise to resolve by using its .then() fucntion, and
  2. Retrieve the found item from the "resolved value". findOneAsync() should pass the found item object as a parameter to its resolve() function (i.e. somewhere inside findOneAsync() 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 with async key, but this code is much cleaner

    const result = await Item.findOne({ where: { id: your_id  } })
    console.log(result)
    

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论