gpt4 book ai didi

javascript - 最好使用单独的JavaScript对象在许多其他JS对象之间共享数据?

转载 作者:行者123 更新时间:2023-12-03 09:27:29 26 4
gpt4 key购买 nike

我正在用PHP和JavaScript构建项目管理应用程序。这个问题更多是围绕JavaScript方面,而更多是架构问题。

因此,我有多个JavaScript对象/类类型文件,这些文件基本上类似于“模块” ...


TaskModal.js
ProjectForums.js
TaskList.js


仅列举一些处理应用程序部分的JavaScript文件。

还有更多。但是它们都具有一个共同点,那就是它们都需要共享访问某些数据位。

例如用户列表。我的大多数JavaScript文件都需要访问数据库中所有用户的用户列表。

因此,为避免我的所有JS文件查询数据库以建立一个单独的用户列表,我打算使用PHP注入Global JS var作为JSON对象,以保存用户列表并允许所有JS文件访问1个用户列表!

为了更进一步,我在第一个JS文件中构建了一个JS函数,该文件将检查是否存在从PHP创建的全局用户列表,如果找不到,则它将发出AJAX请求并获取列表。本身!

如果必须使用AJAX提取列表,则将其设置为其他JS文件的Global userList变量,以希望也避免发出自己的AJAX请求。

因此,用户列表将被缓存,以供所有人访问,并提供冗余后备以确保其已加载!

在我的TaskModal.js文件中,这是我添加此AJAX后备广告的第一个文件,用于检查Global范围中的Userlist,然后在Global中找到它,它将缓存到本地var。如果不是,则发出AJAX请求。

通过这种理论和设计,我基本上需要在所有JS文件中复制相同的用户功能,并且我认为这也许不是他的最佳方法。

我是否应该改用一个单独的User对象来处理上述所有功能,并且单独JS文件上用户的唯一功能将仅仅是访问该User对象?

下面是一个简单的示例,说明TaskModal.js对象具有其自己的用户功能。是否应该将所有这些内容移到单独的User对象?如果是的话,这是否会使从我所有JS文件访问用户数据的想法变得更加有趣?

(function (window, document, $, undefined) {
"use strict";

//we cache a few useful values, like jQuery wrapped window and document
var $window = $(window),
$document = $(document),

projectTaskModal = {

// Cache Properties
cache: {

isUserObjLoaded: false,
userList: '',
isAjaxRequestPending: false,
getUserListUrlEndpoint: '/post',
user: {},
deferred: '',
},


/**
* Initialize projectTaskModal Object and fire off some other init functions
* @return {[type]} [description]
*/
init: function() {
projectTaskModal.users.initUserList();
projectTaskModal.users.getUserList();
projectTaskModal.cache.user = projectTaskModal.users.getUserById('1gdfgdfkn123423423');

console.log('cached User object:', projectTaskModal.cache.user);
},



// Get Userlist and other user related functions
users: {

initUserList: function() {

// check for local Flag indicating that Userlist has been loaded.
// a userlist loaded into DOM as Global var from PHP
if(projectTaskModal.cache.isUserObjLoaded){

// Local copy of userlist has already been loaded so we will not search for
// it in the Global DOM + Not make a server AJAX request to load it
//
// Just return our local cached copy of Userlist
return projectTaskModal.cache.userList;

}else{

// this.cache.isUserObjLoaded is FALSE so we must search Global DOM for userlist
// generated from PHP.

if (!window.hasOwnProperty('globalUserList')) {

alert('Global userlist is not loaded so load it ourself using AJAX request');
// Global userlist is not loaded so load it ourself using
// AJAX request and Promise.
var loadUserListAjax = projectTaskModal.users.ajaxLoadUserListData()
.done(function(response) {
console.log(response);
alert('AJAX request success');

// Parse JSON response var
var userListJson = response;

// next set FLAG that userList is loaded
projectTaskModal.cache.isUserObjLoaded = true;

// After loading userlist from server, cache it locally and to global var for other
// JS scripts to use and prevent them from also making AJAX requests!

projectTaskModal.cache.userList = userListJson;

window.globalUserList = userListJson.user_list;

projectTaskModal.cache.isAjaxRequestPending = false;

projectTaskModal.users.getUserList();


}).fail(function(response) {
// AJAX request failed
console.log('response', response);
alert('AJAX request failed');
}).always(function(response) {
projectTaskModal.cache.isAjaxRequestPending = false;

// Hide Loader/Spinner
setTimeout($.unblockUI, 1000);
});



}else{

alert('Global userlist is loaded so cache it locally and do not make AJAX request!');
// cache the Global userlist var to local property
projectTaskModal.cache.userList = window.globalUserList;

// next set FLAG that userList is loaded
projectTaskModal.cache.isUserObjLoaded = true;

projectTaskModal.users.getUserList();

}
}
},


ajaxLoadUserListData: function() {
projectTaskModal.cache.isAjaxRequestPending = true;
return $.ajax({
type: 'POST',
async: true,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
url: '/restful/fortune',
data: {
action: 'load-userlist'
},
});
},



getUserList: function() {
if(projectTaskModal.cache.isUserObjLoaded){

console.log('userList',projectTaskModal.cache.userList);
}else{
console.log('userlist Obj not loaded =(');
}
},


getCurrentUser: function(user_id) {
if(projectTaskModal.cache.isUserObjLoaded){
myUserData[1].username
console.log('userList',projectTaskModal.cache.userList);
}else{
console.log('userlist Obj not loaded =(');
}
},


getUserById: function(user_id) {
var userList = projectTaskModal.cache.userList;
for (var i = 0; i < userList.length; i++) {
if (userList[i].id === user_id) {
user = {
id: userList[i].id,
username: userList[i].username,
role: userList[i].role,
gravatar: userList[i].gravatar,
}
return user;
}
}
throw "Couldn't find object with user_id: " + user_id;
},

},
};


// Run Init on DOM Ready
$(function() {
projectTaskModal.init();

});

}(this, document, jQuery));




浪费的记忆?

在当前方法中,我没有单独的User对象。我基本上将用户列表存储在:


全局变量
3个单独的JS对象文件中的每一个的本地变量


好像会浪费很多内存?将用户列表和数据存储在其自己的专用用户对象中是否会将4x用户列表减少到1?



快速阅读-目标概述

我的项目管理应用程序中有3个或更多JavaScript文件/对象,它们都需要访问共享数据,例如 UserlistDebug/MockingMilestones ListTags List等!

与其让每个目标文件都通过AJAX请求从服务器中加载数据,不如在同一页面加载中一遍又一遍地加载相同的内容,我想加载一次并缓存并在所有JS对象/文件之间共享。

因为我是JS新手,所以我不确定在没有使用第三方库的情况下实现此目标的最佳途径! (jQuery可以)

为了简单起见,假设有3个JS对象/文件,并且用户列表是它们之间唯一共享的对象。

在页面加载中,我第一次尝试使用PHP将用户列表作为JSON对象加载到DOM中作为全局变量。

我希望有一个备用,如果找不到,则JS可以发出AJAX请求来加载用户列表(如果需要)。 IT将加载用户列表,将其存储在本地以供工作对象使用,然后将其作为Global变量进行缓存,就像PHP应该做的那样!全局缓存后,下一个用于检查“全局用户列表”的JS文件应该找到它并将其本地缓存到自身中,而无需执行任何服务器请求。

我在这里担心的是,我需要在所有3个JS对象/文件中复制这种加载/缓存机制!

我还认为这可能会导致占用大量内存,这是可以避免的?

所以我的主要问题是,我上面描述的方式看起来像是一种不好的方法吗?我提到的问题是真正的问题吗?然后,如果这都是真的,那么更好的替代路线是什么?

我在想,也许不必将所有这些User代码复制到3个object / JS文件中,而可以改为拥有自己的 User{}对象。

如果有一个User对象来处理加载Userlist并检查它的存在以及所有其他东西,那么我将如何最好地访问其他3个JS对象/文件中的User对象数据?

我希望这是合理的,我很难解释。

最佳答案

您可以通过使一组js文件处理数据层来进一步分离您的关注点。我们可以将其命名为services。还有另一组modules,它将处理应用程序(或UI插件,例如图片库)的流程并使用由数据层管理的数据。这听起来很漂亮,也很有趣,让我们以我喜欢在某些项目上使用的模式跳入代码。

在我加载的第一个js文件中,我为项目定义了一个全局名称空间

// main.js
(function(){
window.MyCoolProject = {
services: {},
modules: {},
helpers: {},
laserGuns: {},
etc: {}
};
})();


这样,我们就可以有组织地将公共方法公开给其余代码,并避免与其他js库发生冲突。然后,我们加载数据层。

// services/user.js
// this file has all the functions required to load user data, these will be a bunch of ajax calls

(function(){

// we can use this to cache data, even though we can cache via jquery. more on this later
var cached = {};

MyCoolProject.services.UserService = {
getUsers: function(callback){
// if the cache object has a 'users' property, we have already loaded this data so we returned the cached version of this. Note that we don't return data, we pass it through a callback as a asynch call
if (cache.users){
callback(cache.users);
return;
}
// if there is no cached data, we make the ajax call
$.ajax({
url: 'path/to/api.json'
method: 'GET',
// jquery also provides a cache for ajax calls, you can experiment with both to see which better suits your needs
cache: true,
success: function(data){
// once loaded we can manually cache the data
cache.users = data;
callback(cache.users);
}
});
},
getUser: function(id, callback){ ... },
etc: function(callback){ ... }
};
})();


这样打电话时

MyCoolProject.services.UserService.getUsers(function(users){
console.log(users); // will be the same list of users, despite how many times you call it. You will get the same cached version
});


进入模块。我相信这些代码可能与您已经拥有的代码相同,但是更改了数据加载方式以调用服务层中的函数(如上)。您可以在不同的文件中调用相同的函数,并且不会有重复的数据。但是有一个js陷阱!

在js中,对象(和数组)作为彼此的引用存储。这意味着要做的事情如下:

var a = {},
b = a,
c = b;


表示 ac相同,并且对 a的任何更改都将反映在 c中。在内部,它是相同的内存块,但是我敢肯定还有比我更有资格解释这一点的人。如果将同一数据对象放入其他位置,则基本上不必担心内存消耗。您需要注意的是,一个模块不会更改该数据,因为其他所有模块都会更改。如果在某些情况下需要更改数据对象,则必须先对其进行克隆(请参见jquery中的$ .extend())。

根据所有这些巨型组件,模块看起来像这样

// modules/userImageGallery.js
// a strange image gallery that shows a mugshot of each user
(function(){
// we autoexecute the module and push its public methods into its namespace
MyCoolProject.modules.UserImageGallery = (function(){

var users = [];

MyCoolProject.services.UserService.getUsers(function(data){
users = data;
});

function next(){ currentUserIndex++; }
function prev(){ currentUserIndex--; }

... etc ...

// we expose the desired methods
return{
next: next,
prev: prev
};
})();
})();

// now we, or any other module, can control the image gallery by calling
MyCoolProject.modules.UserImageGallery.next();


请注意,在javascript中可以使用几种模式。有闭包,原型,单例(带有函数的对象)等。重要的是将公共函数推入相应的全局名称空间中。

我希望现在您可以看到这对您的代码组织有何好处,您可以继续增长并添加模块和服务,并使所有内容井井有条,而且对其他用户也可以使用。附带的好处是您可以通过控制台访问这些方法,因此可以更轻松地运行测试。

展望未来

鉴于您提到您是javascript新手,我建议像您一样使用无框架方法。这样,您将学习js的所有调整和好处。一旦感到舒适,请考虑研究角度或余烬或任何其他数据绑定框架。这些提供了改进的关注点分离,对应用程序流的更多控制,改进的安全性和依赖性管理。希望您喜欢!

关于javascript - 最好使用单独的JavaScript对象在许多其他JS对象之间共享数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31622621/

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