【发布时间】:2017-08-26 05:48:21
【问题描述】:
不,你不是我的妻子,但最近我和你在一起的时间肯定比她多。
无论如何,我正在将一个 php 站点转换为 node.js,并且已经掌握了创建猫鼬模式和模型的窍门。唯一奇怪的是,您需要模型能够对数据库进行任何查询。
所以我一直 var etc = require("./models/etc");'ing 我的模型将在我的 index.js 服务器中用于 app.get 请求。我model.find我想要的数据并将它传递给jade/pug模板渲染。
这没关系,因为在我的所有模型文件中,我都是手动创建模式的,即:我编写对象,然后用它制作模型,然后使用这些模式创建文档并保存它们。
但是,现在我有一个产品模式/对象,它依赖于从 shopify api 获取产品,使用节点模块 generate-schema 从该产品中创建一个模式,然后创建模型,然后遍历来自 shopify 的产品,为每个文件创建一个新文档并附加一些图像 url 和一些其他属性,然后保存文档。
这一切都发生在一系列 .then(function()) 中,其中一个 objects 对象通过整个链传递并存储我需要的每个函数的所有变量。然后在该承诺链的末尾,我尝试使用 module.exports = objects.variable (在这种情况下,它是一个猫鼬模型)。但是因为在 index.js 中,当我 var product = require('./models/products') 它异步执行此操作时,变量 product 只是 {} 而不是等待 .then 承诺链发生然后使用模块。 export 写在最后。
有没有办法让 require(x) 等待 module.exports 被填充或等到整个文件运行正常后再分配变量?
谢谢。
如果你需要,这里是代码
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;
});
而在 index.js 中简直就是
var product = require('./models/products');
console.log(product);
输出:
{}
【问题讨论】:
-
你应该导出promise本身,并使用
require('./models/products').then(console.log) -
@bergi 但是猫鼬模型的目的是在应用程序的整个生命周期中保存,而不仅仅是为了那个承诺线程。
-
你所说的“那条承诺”是什么意思?承诺值 在应用程序的整个生命周期内存储在模块注册表中。
-
是的,但是你不会将它用作 require('./models/products').then(x) 你会去 var x = require('./models/products') ;然后稍后在应用程序中转到 x.then(etc..) 对吗?
-
出现 require(x).then 不是函数?
标签: javascript node.js mongodb mongoose