gpt4 book ai didi

Javascript 数据层架构协助

转载 作者:行者123 更新时间:2023-11-27 22:41:59 26 4
gpt4 key购买 nike

我正在制作一个相当复杂的 HTML 5 + Javascript 游戏。客户端将不得不根据他们所在的区域在游戏的不同点下载图像和数据。我在解决 Javascript 架构的数据层部分的一些问题时遇到了很大的问题。

我需要用数据层解决的问题:

  1. 每当调用服务器以检索新数据时,应用程序中使用的过时数据都需要自动更新。
  2. 从服务器检索的数据应存储在本地,以减少因两次请求相同数据而产生的任何开销。
  3. 无论数据是否已在本地可用,任何需要访问数据的代码部分都应该能够以统一的方式轻松检索数据。

我尝试做的是构建一个包含两个主要组件的数据层:1. 允许访问数据的层部分(通过 get* 方法)2. 存储本地数据并将其与来自服务器的数据同步的层部分。

工作流程如下:

当游戏需要访问某些数据时,它会在数据层中为该数据调用 get* 方法,并传递一个回调函数。

bs.data.getInventory({ teamId: this.refTeam.PartyId, callback: this.inventories.initialize.bind(this.inventories) });

get* 方法确定数据是否已在本地可用。如果是这样,它要么直接返回数据(如果没有指定回调),要么调用回调函数将数据传递给它。

如果数据不可用,它会在本地存储回调方法 (setupListener) 并调用通信对象传递最初请求的信息。

getInventory: function (obj) {

if ((obj.teamId && !this.teamInventory[obj.teamId]) || obj.refresh) {
this.setupListener(this.inventoryNotifier, obj);
bs.com.getInventory({ teamId: obj.teamId });
}
else if (typeof (obj.callback) === "function") {
if (obj.teamId) {
obj.callback(this.team[obj.teamId].InventoryList);
}
}
else {
if (obj.teamId) {
return this.team[obj.teamId].InventoryList;
}
}
}

通信对象然后向服务器发出 ajax 调用并等待数据返回。

当返回数据时,再次调用数据层,要求它发布检索到的数据。

getInventory: function (obj) {
if (obj.teamId) {
this.doAjaxCall({ orig: obj, url: "/Item/GetTeamEquipment/" + obj.teamId, event: "inventoryRefreshed" });
}
},
doAjaxCall: function (obj) {

var that = this;

if (!this.inprocess[obj.url + obj.data]) {
this.inprocess[obj.url + obj.data] = true;
$.ajax({
type: obj.type || "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: obj.data,
url: obj.url,
async: true,
success: function (data) {
try {
ig.fire(bs.com, obj.event, { data: data, orig: obj.orig });
}
catch (ex) {
// this enables ajaxComplete to fire
ig.log(ex.message + '\n' + ex.stack);
}
finally {
that.inprocess[obj.url + obj.data] = false;
}
},
error: function () { that.inprocess[obj.url + obj.data] = false; }
});
}
}

数据层然后将所有数据存储在本地对象中,最后调用原始回调函数,将请求的数据传递给它。

publishInventory: function (data) {

if (!this.inventory) this.inventory = {};

for (var i = 0; i < data.data.length; i++) {
if (this.inventory[data.data[i].Id]) {
this.preservingUpdate(this.inventory[data.data[i].Id], data.data[i]);
}
else {
this.inventory[data.data[i].Id] = data.data[i];
}
}

// if we pulled this inventory for a team, update the team
// with the inventory
if (data.orig.teamId && this.team[data.orig.teamId]) {
this.teamInventory[data.orig.teamId] = true;
this.team[data.orig.teamId].InventoryList = [];
for (var i = 0; i < data.data.length; i++) {
this.team[data.orig.teamId].InventoryList.push(data.data[i]);
}
}

// set up the data we'll notify with
var notifyData = [];

for (var i = 0; i < data.data.length; i++) {
notifyData.push(this.inventory[data.data[i].Id]);
}

ig.fire(this.inventoryNotifier, "refresh", notifyData, null, true);
}

有几个问题一直困扰着我。我会按照最烦人的顺序列出它们:)。

  1. 任何时候我都必须添加一个通过此过程的调用,这样做会花费太多时间。 (至少一个小时)
  2. 跳转和回调传递的数量令人困惑,而且似乎很容易出错。
  3. 我存储数据的分层方式非常难以同步和管理。接下来会详细介绍。

关于上面的问题 #3,如果我在数据层中存储的对象具有如下结构:

this.Account = {Battles[{ Teams: [{ TeamId: 392, Characters: [{}] }] }]}
this.Teams[392] = {Characters: [{}]}

因为我想以一种可以传递 TeamId 来检索数据的方式存储 Teams(例如 return Teams[392];),但我还想存储与它们所在的战斗 (this.Account.Battles[0].Teams[0]);我有一段时间的噩梦,让同一个团队的每个实例都保持新鲜并维护相同的对象标识(所以我实际上并没有存储它两次,这样我的数据就会在任何使用它的地方自动更新,这是目标#1数据层)。

它看起来很杂乱。

非常感谢任何帮助。

谢谢

最佳答案

您应该考虑使用 jquery 的延迟对象。

例子:

var deferredObject = $.Deferred();
$.ajax({
...
success: function(data){
deferredObject.resolve(data);
}
});
return deferredObject;

现在返回了 deferredObject,你可以像这样给它附加回调:

var inventoryDfd = getInventory();
$.when(inventoryDfd).done(function(){
// code that needs data to continue
}

而且您可能不太容易出错。您甚至可以嵌套延迟对象,或组合它们,以便在下载多个服务器调用之前不会调用回调。

关于Javascript 数据层架构协助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10361036/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com