存储和检索函数及其上下文

Storing and retrieving functions and their context

我正在制作一个离子应用程序,我想在其中为用户提供离线功能(即操作缓存的数据)。

例如:用户试图在离线时更改他的头像。我通过

这样做
  1. 首先更改缓存的用户配置文件对象
  2. 然后应用程序尝试更新云数据库中的用户配置文件对象。
  3. 由于没有互联网连接,我存储了保存函数、它的上下文(它所属的 class 对象)和对象的参数(如果有的话)。
  4. 我将这个对象存储到一个队列中。 (我正在使用这个队列来存储之前由于没有互联网连接而无法执行的任何其他操作)
  5. 我在我的应用程序中创建了一个 "sync service" 订阅了我的 "connectivity-service" 发布的 "internet OK" 事件
  6. 当我的同步服务接收到 internet OK 事件时,它循环遍历队列并执行它们应有的操作

当用户关闭应用程序时,队列中的数据丢失,所以我必须将其存储到 memory.The 这里的问题是当我尝试将我的队列对象存储到缓存(indexDB)中时,我得到JSON 由于我队列中对象的循环性质而导致的错误。我不确定这是否是为具有离线功能支持的应用程序保留数据的正确做法。我在正确的轨道上吗?一旦我有互联网,我如何才能实现需要与云中的数据库交互并保留用户数据的离线功能?

我正在考虑将函数名称(用于保存用户的函数)保存为字符串,对于包含此函数的 class 也是如此。然后我可以将逻辑添加到我正在执行这些操作的循环部分,这些操作将调用右 class 的右函数。这似乎需要做很多工作,因为我需要登录才能知道哪个字符串映射到哪个 class 以及哪个函数。

我本来可以使用 couch DB 和 pouch DB,但我的项目还很深入,我将不得不重新开始。

let obj = {
  retry: retry,
  error:error,
  function: f,
  context: context,
  args: args
};

this.syncService.addToJobsQueue(obj);

然后在我的同步服务中我做了这样的事情:

subscribeToConnectivityService(){
console.log("subscribeToConnectivityService");
let me = this;
me.events.subscribe("connectivity-service-event:internet", (val) => {
  console.log("connectivity-service-event:internet : " + val);
  if(val){
    me.completeJobsInQueue();
  }
});}


completeJobsInQueue(){
console.log("completeJobsInQueue");
let me = this;
me.localDBStorage.getJobsQueue().then((response) => {
    if(response==null){response = {}}
    return response;
}).then((jobsQueue) => {
    //clean the jobs queue first
    me.createEmptyJobsQueue();
    for (var key in jobsQueue) {
        me.executeJob(jobsQueue[key]);
    }
}).catch((ex) => {
    console.error('Error getting jobsQueue from localDBStorage: ', ex);
    me.createEmptyJobsQueue();
});}

然后我执行这样的功能:

executeJob(job){
    console.log("executeJob");
    var f = wrapFunction(job.function, job.context, job.args);
    (f)();
}

var wrapFunction = function(fn, context, params) {
    return function() {
        fn.apply(context, params);
    };
}

有没有一种方法可以将指向 class 和函数的指针存储到缓存中?或我可以实施的任何其他不需要我进行重大更改的技术?

好的,经过一番挖掘,我终于能够解决这个问题。我做了以下步骤:

1 - 我从对象

更改了保存在队列中的对象(最终将作为 JSON 存储到缓存中)
let obj = {
  retry: retry,
  error:error,
  function: f,
  context: context,
  args: args
};

我将函数和上下文对象更改为只有一个字符串值。对于保存用户配置文件对象的函数,我将其签名 "saveUser" 及其上下文 class "CloudService" 保存为字符串,如下所示:

obj.context = "saveUser"
obj.context = "CloudService"

然后我摆脱了 wrapFunction,而是在我的 executeJob 函数中发布了一个 syncServiceEvent 作为:

executeJob(job){
    this.events.publish("syncServiceExecuteJob", job);
}

现在,在我希望提供某种离线功能支持的所有服务中,我订阅了该活动 "syncServiceExecuteJob"

events.subscribe("syncServiceExecuteJob", (val) =>{
      let me = this;
      me.syncEventExecuter(val);
});

接下来我创建一个同步服务事件执行器,只是简单地验证服务收到的事件是否包含针对它的作业,否则忽略它:

syncEventExecuter(val){
    console.log("syncServiceExecuteJob");
    console.log(val);
    if(this.constructor.name == val.context){
      this[val.function](val.args);
    }
}

this[val.function](val.args); 使用正确的参数数组执行正确的函数。

我仍然不是 100% 的天气,这是在支持离线功能的应用程序中处理数据持久性的正确方法,但目前它似乎可以正常工作。我在这件事上没有受过良好的教育,希望得到这里专家的建议:)