【问题标题】:Storing and retrieving functions and their context存储和检索函数及其上下文
【发布时间】:2017-07-03 09:11:53
【问题描述】:

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

例如:用户在离线时尝试更改其个人资料图片。我是这样做的

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

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

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

我会使用 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);
    };
}

有没有办法将指向我想要使用的类和函数的指针存储到缓存中?或者我可以实施的任何其他不需要我进行重大更改的技术?

【问题讨论】:

    标签: json caching local-storage persistence


    【解决方案1】:

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

    1 - 我从对象更改了保存在队列中的对象(最终将作为 JSON 存储到缓存中)

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

    我将函数和上下文对象更改为只有一个字符串值。对于将保存用户配置文件对象的函数,我将其签名“saveUser”及其上下文类“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% 的天气,这是在支持离线功能的应用程序中处理数据持久性的正确方法,但现在它似乎正在工作。我在这件事上没有受过良好的教育,希望这里的专家提供建议:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2013-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多