简体   繁体   English

从文件中请求猫鼬模型,该文件在一系列promise.then.then链期间创建模型。

[英]Requiring a mongoose model from a file which creates the model during a series of promise.then.then chains.

no, you're not my wife, but it sure seems I spend more time with you than her lately. 不,您不是我的妻子,但可以肯定的是,我最近和您在一起的时间比她多。

Anyway, I'm converting a php site to node.js and have gotten the hang of creating mongoose schemas and then models. 无论如何,我正在将一个PHP网站转换为node.js,并迷上了创建猫鼬模式和模型的过程。 The only odd part is the fact that you need the model to be able to do any queries on the database. 唯一奇怪的是,您需要模型才能对数据库执行任何查询。

So I've been var etc = require("./models/etc");'ing my models to be used in my index.js server for app.get requests. 所以我一直在var etc = require(“ ./ models / etc”);'ing我的模型在我的index.js服务器中用于app.get请求。 I model.find the data I want and pass it to a jade/pug template render. 我对所需的数据进行建模,然后将其传递给Jade / Pug模板渲染。

This has been okay because in all my model files I create the schemas by hand, ie: I write the object, then make a model out of it, and then create documents with those schemas and save them. 之所以可以这样做是因为,在我所有的模型文件中,我都是手动创建模式的,即:先编写对象,然后用该模型创建模型,然后使用这些模式创建文档并保存。

But, now I have a product schema/object which relies on fetching products from a shopify api, creating a schema out of that product with a node module generate-schema, then creating the model, then looping through the products from shopify, creating a new document for each and appending some image urls and a couple of other properties and then saving the document. 但是,现在我有了一个产品架构/对象,该产品依赖于从shopify api获取产品,使用节点模块generate-schema从该产品中创建一个架构,然后创建模型,然后遍历shopify中的产品,创建一个每个文档都有一个新文档,并附加了一些图片网址和几个其他属性,然后保存该文档。

This all happens in a series of .then(function())'s where an objects object is passed through the entire chain and stores all the variables I need from each function. 所有这一切都发生在一系列.then(function())中,在该序列中,对象对象通过整个链传递,并存储我需要从每个函数获取的所有变量。 Then at the end of that promise chain I try to module.exports = objects.variable (in this case it's a mongoose model). 然后,在该承诺链的末尾,我尝试使用module.exports = objects.variable(在这种情况下,它是猫鼬模型)。 But because in index.js when I var product = require('./models/products') it does this asynchronously so the variable product is just {} instead of waiting for the .then promise chain to occur and then use the module.exports which is written at the end. 但是因为在index.js中,当我var product = require('./ models / products')时,它是异步进行的,因此变量product只是{}而不是等待.then promise链出现然后使用该模块。出口是写在最后。

Is there a way to make require(x) wait for the module.exports to be populated or wait until the whole file has run it's course before assigning the variable? 有没有一种方法可以让require(x)等待module.exports填充,或者等到整个文件运行完毕,再分配变量?

Thank you. 谢谢。

Here's the code if you need it 这是您需要的代码

var MongoClient = require('mongodb');

// mongodb = MongoClient.connect('mongodb://localhost/myleisure');

var mongoose = require('mongoose');

var fs = require('fs');
var path = require('path');

var generateSchema = require('generate-schema');

// mongoose.connect("mongodb://localhost/myleisure");
//
// var db = mongoose.connection;

var Schema = mongoose.Schema;


var shopify = require('shopify-buy');

var client = shopify.buildClient({
  accessToken: 'private',
  domain: 'my-leisure.myshopify.com',
  appId: 'X'
});




var write = true;

//Only uncomment if you want to export hell
// module.exports = function (callback) {

client.fetchProduct('8461073805').then(function(products) {
  var objects = {};

  objects.schema = generateSchema.mongoose(products.attrs.variants[0]);
  objects.products = products;

  return objects;

})
.then(function(objects){

  var productSchema = new Schema(objects.schema);

  productSchema.add({
    images: {type: [], default: null},
    thumbnail: {type: String, default: "thumb.jpg"},
    name: {type: String, default: "lettini"},
    colour: {type: String, default: null},
    finish: {type: String, default: null},
    size: {type: String, default: null},
    id: {type: String, default: objects.products.attrs.product_id},
    variantId: {type: String, default: null}
  });

  var product = mongoose.model("product", productSchema);


  product.remove({});
  objects.product = product;
  // callback(product)
  return objects;

}).then(function(objects){

  if(write)
    return objects.product.remove({name: "lettini"}).then(function(){

      return objects
    });

}).then(function(objects){
  if(write)
    var productsDir = "./img/products/lettinis/400x";
    var products = objects.products;
    var product = objects.product;
    // console.log(products.variants.length);
    // console.log(i);

    // console.log(schema);
    // console.log(products.attrs.variants);

    fs.readdir(productsDir, (err, skus) => {
      skus.forEach(sku => {
        for (var i = 0; i < products.variants.length - 1; i++) {
          if ( products.variants[i].attrs.variant.sku === sku) {

            var tempProduct = products.variants[i].attrs.variant;
            var newProduct = new product(tempProduct);

            fs.readdir(productsDir + "/" + sku, (err, images) => {
              images.forEach(image => {
                newProduct.colour = tempProduct.option_values[1].value;
                newProduct.frame = tempProduct.option_values[2].value;
                newProduct.size = tempProduct.option_values[0].value;
                newProduct.images.push(image);
              });
              newProduct.save();
            });

          };
        };
      });
    });

    return objects

}).then(function(objects){
  // console.log(objects.product);
  module.exports = objects.product;
});

And in the index.js is simply 并且在index.js中只是

var product = require('./models/products');
console.log(product);

output: 输出:

{}

Then at the end of that promise chain I try to module.exports = objects.variable (in this case it's a mongoose model). 然后,在该承诺链的末尾,我尝试使用module.exports = objects.variable (在这种情况下,它是猫鼬模型)。 But it does this asynchronously 但这是异步执行的

Don't asynchronously export something. 不要异步导出内容。 Export the promise instead - immediately: 而是立即导出诺言:

module.exports = client.fetchProduct(…).then(…)
.…
.then(function(objects){
  // console.log(objects.product);
  return objects.product;
});

So that you can use the promise techniques (also things like Promise.all in case you load more modules) to wait for it in index.js: 这样您就可以使用promise技术(在加载更多模块的情况下也可以使用Promise.all东西)在index.js中等待它:

require('./models/products').then(function(product) {
  console.log(product);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM