返回在Mongoose中声明的变量find()

时间:2017-07-08 22:06:53

标签: javascript node.js mongodb mongoose

我在将for循环与promises结合起来时遇到了很多麻烦。从本质上讲,我的工作流程是:

  1. 在Node.js中获取一系列 Artist 对象,然后抓住它们 使用Mongoose的传记和身份证。
  2. 使用他们的ID获取所有艺术作品(更具体地说,所有作品 由该艺术家创作的艺术品关键词。
  3. 在自然语言处理器分类器中训练它们(这部分 不是超级相关 - 只知道我需要访问 同一外部范围内的 biography keywords
  4. 但是,我似乎无法在Mongoose承诺中使用 bioText 对象,而且似乎无法从Mongoose承诺中返回关键字。

                if (!isBlank(bioText) && bioText){
                    bioText = artist.BIO;
                    artworkIdArray.forEach((id)=> {
                            console.log(bioText) // <- prints correct values
                            var getKey = function(){
                        var words = Artwork.findById(id).then((artwork)=>{
                            console.log(bioText) // <- empty string
                        if(artwork.artworkKeywords.length > 0){
                            keywords = artwork.artistKeywords;
                            return keywords;
                        }
                    }
                    )
                    return words;    
                    }
                    t=getKey();
                    t.then((t)=>{
                        console.log(t); // <--- always undefined
                    })
                }, this);
            }
    

    正如您所看到的,我在退出承诺后尝试 console.log() ,但 t 对象始终未定义。

    此外,

    我知道在我的示例 bioText 可用,直到Mongoose find() 承诺。但我也不知道如何将 bioText 注入承诺(因为那时我只需在 then() 语句中训练分类器

    所以我的帖子基本上是两个问题:

    1. 可以承诺在 then()
    2. 中使用外部变量
    3. 如何返回在 then() 内声明的变量 在外部范围内可用吗?

1 个答案:

答案 0 :(得分:1)

  
      
  1. 可以承诺在then()中使用外部变量吗?
  2.   

是的,但是你必须要小心这些变量后来会发生什么。 这就是console.log(bioText)可能在DB调用之前记录一个值,然后在DB响应之后记录null的原因。

我建议您尝试立即调用模式以确保该值是预期值:

(function(x){...; console.log(x);})(bioText)
  
      
  1. 如何返回then()内声明的变量,以便它可用   在外部范围?
  2.   

你不能,至少没有复杂的承诺管理,你可能不需要这里。 这就是为什么t=getKey();总是undefined

我认为您希望在继续处理之前获取所有值。因此,您应该在单个查询中从数据库中检索所有内容,然后在回调中调用所有代码。

您可以试试这个:

Artwork
    .find({_id: {$in: artworkIdArray}})
    .then( (artworks) => {
        var keywords = [];
        artworks.forEach( (artwork) => {
            if(artwork.artworkKeywords.length > 0)
                keywords.append(artwork.artistKeywords);
        });
        // Now do your job with all the retrieved keywords
    });