2017-04-11 99 views
0

为了试图重构将在不同地方使用的一些代码,我将此方法从控制器移到了Mongoose模型。Mongoose - 查询exec()永远不会在模型方法中解决

在模型中,trackQuery.exec()永远不会回调,永远不会解决。如果我解决没有exec()或没有等待exec(),它工作正常。 trackQuery用Mongoose Query正确填充。

我不明白Mongoose模型的微妙之处?

ArtistSchema.methods.insertRelatedTracks = function (items) { 
    const newTracksToSave = items.map((item) => { 
     return new Promise((resolve, reject) => { 
      const TrackModel = mongoose.model('Track'), 
       trackQuery = TrackModel.findOne({ externalID: item.id }) 
      ; 

      return trackQuery.exec((err, track) => { 
       if (err) { 
        return reject(err); 
       } 

       if (!track) { 
        let track = new TrackModel({ 
         externalID: item.id, 
         provider: item.provider, 
         title: item.title, 
         artist: item.artist, 
         artistID: this._id, 
         artistExternalID: this.externalID, 
         thumbnail: item.thumbnail, 
         publishedAt: item.publishedAt, 
         count: 0 
        }); 

        return track.save((err, res) => { 
         if (err) { 
          return reject(err); 
         } 

         return resolve(res); 
        }); 
       } 

       return resolve(track); 
      }); 
     }); 
    }); 

    return Promise.all(newTracksToSave).then(() => { 
     return this; 
    }).catch((err) => { 
     console.error(err); 
     return this; 
    }); 
} 

回答

0

为我的解决方案是手动导入TrackModel而不是依赖于通常的运行时mongoose.model('Track')方法。我没有解释为什么mongoose.model在这种情况下不起作用。欢迎任何提示。

+0

这可能与你的问题没有关系,但'.exec()'已经返回一个promise,所以不需要用一个额外的'new Promise(...)'来包装Mongoose查询。你当前的代码的一个可能的问题是,如果一个轨道不存在,你仍然解决一个空的/未定义的'track'变量的承诺,并且它将解析对'resolve(res)'的调用。所以代码应该是'if(!track){...} else {return resolve(track)}' – robertklep

+0

@robertklep感谢您的评论! :)这绝对没有关系,因为代码中唯一的区别就是导入'TrackModel'的方式。另一方面,我的印象是Promises或不是'return'会在相同的范围内停止执行。 'return track.save ...'可以防止达到'return resolve(track);'如果没有轨道。我错了吗? – Azuli42

+1

对不起,我的错,我错过了'track.save()'前面的'return'。请忽略我评论的那部分; D – robertklep