【发布时间】:2018-05-09 15:21:46
【问题描述】:
这是一个关于如何处理 API 中不断变化的数据依赖关系的一般问题。
我在我的应用程序中依赖两个数据对象:
1. mycompanyProducts
2. mycompanySettings
产品对象如下所示:
{
"MYTHING01": {
"sku": "MYTHING01",
"name": "15-Pack",
"price": 30,
"shopifyData": {
"id": "7987037995068",
"product_id": "664292996940",
"price": "30.00",
"taxable": true,
"inventory_quantity": 10,
"weight": 2,
"weight_unit": "kg",
"lastFetched": {
"$date": "2018-05-09T14:16:57.209Z"
}
}
},
"MYTHING02": {
"sku": "MYTHING02",
"name": "5-Pack",
"price": 15,
"shopifyData": {
"id": "7836960168028",
"product_id": "645959671756",
"price": "15.00",
"taxable": true,
"inventory_quantity": 10,
"weight": 2,
"weight_unit": "kg",
"lastFetched": {
"$date": "2018-05-09T14:16:57.228Z"
}
}
}
}
设置对象仅包含应用程序设置,例如最大图片上传大小(以 MB 为单位)等。
这两个对象都来自 MongoDb 集合。
我的想法是:我希望能够更新我的集合,并让我的 API 更新其依赖项,而无需重新构建。必须触发基于 Shopify webhook(其中一些更改的来源)等的 API 重建会非常麻烦。
每个产品都有一个shopifyData.lastFetched时间戳,在访问数据时,如果时间戳超过过去的某个时间段(10分钟),我想在继续之前刷新数据:
// Loop through each Shopify product and update the product in the db
await Promise.all(res.data.products.map(async (shopifyProduct) => {
const variant = shopifyProduct.variants.find(v => mySKUs.includes(v.sku))
product.shopifyData = {
...variant,
lastFetched: new Date(),
}
await product.save()
}))
问题是:如何构建我的 API 以使用更新依赖项?显然 ES6 模块是静态导出的,在应用程序重建之前不会改变。
我当然可以导出一个返回依赖的函数,当我需要新的deps时调用这个函数,但问题是我的函数必须是async,所以很难打电话:
import React from 'react'
const deps = generateDeps() // can't use await in this scope...
此外,将const deps = generateDeps() 放在我的文件顶部并不能真正解决问题,因为这只会被评估一次。
人们如何解决这个问题?
【问题讨论】:
-
目前还不清楚为什么 Shopify 产品或产品系列的更新应该更新您的项目依赖项。比如...更新产品意味着您需要将一个新的、不同的 npm 模块加载到您的项目中?
-
我问的原因是因为我直觉地觉得你遇到这个问题的原因是你首先构造了错误的东西。如果您只需要更新产品信息……那不需要像您要求的那样复杂。
-
您似乎将数据模型的概念、实际数据和对数据的访问权混为一谈,称为dependencies。在您的场景中,这些事情中只有一个实际发生了变化,正如 TKoL 指出的那样,您不需要所有这些复杂的事情来更新数据。
-
@RandyCasburn 显然更新数据是很容易的部分。想象一下我改变了
MYTHING02的体重。如果我的 API 的其他部分依赖这个权重 - 想象一个端点的验证检查权重 - 这种变化将如何发生?没有必要居高临下。 -
道歉 - 不是故意的 - 看来你的困境是同步。解决方案从最简单的 pub/sub 开始,到最复杂的响应式 javascript (RxJS) 样式的 observables。订阅更改的数据并通过自定义事件传播这些更改,或者观察数据并对更改做出反应。
标签: javascript asynchronous dependency-injection ecmascript-6 promise