【问题标题】:JS save data THEN redirectJS 保存数据 THEN 重定向
【发布时间】:2020-12-31 15:04:15
【问题描述】:

我正在使用 js 和 jsPsych 编写实验代码。

在任务结束时,我想将数据保存到 Firebase Firestore,然后重定向到某个位置。但是,当我包含 window.location.replace 时,当前没有保存任何数据。 没有重定向它工作正常。但我两者都需要。任何建议将不胜感激。

jsPsych.init({
timeline: timeline,
preload_images: [
  on_finish: function() {(saveData(jsPsych.data.get().json()));
    (window.location.replace("https://url.com"));
  },
      });

  function saveData(data){
    console.log("trying to save");
    const db = firebase.firestore();
    var data = JSON.parse(data);
    var namedData = {};
    data.forEach(function(q) {
 
    //console.log(q.internal_node_id)

    if(q.hasOwnProperty("responses"))
    {
      q.responses = JSON.parse(q.responses);
    }
    namedData[q.internal_node_id] = q;

  })
    //db.collection("user").doc(subject_id).set(namedData)
    db.collection("user").doc(subject_id).set(namedData)
      .then(function() {
        console.log("data saved")
      })
  }

非常感谢!

【问题讨论】:

  • 在 Promise set(namedData) 解决之前,您是否正在离开页面?为了验证这个假设,您可以将您的 window.location.replace 移动到最后一个 then 函数的主体中,然后查看数据库写入是否有效。
  • 您的重定向发生在保存数据之前。对saveDatawindow.location.replace 的调用是同步的。尽管如此,当您使用 Promise db....then 时,saveData 本身是异步的。因此,您无需等待插入数据库完成即可重定向。所以是的,很可能数据正在保存,只是在您重定向时不正确,但稍晚一点。查看 JavaScript 的 async/await 以获得可能的解决方案,或将重定向放入 then 回调中。

标签: javascript firebase google-cloud-firestore jspsych


【解决方案1】:

有人评论说:您当前正在将数据保存到数据库之前进行重定向。为防止这种情况发生,您必须等到数据保存后,您可以使用您当前正在使用的then() 进行记录。

所以:

  on_finish: function() {
    saveData(jsPsych.data.get().json());
  },
});

  function saveData(data){
    console.log("trying to save");
    const db = firebase.firestore();
    var data = JSON.parse(data);
    var namedData = {};
    data.forEach(function(q) {
 
      if(q.hasOwnProperty("responses")) {
        q.responses = JSON.parse(q.responses);
      }
      namedData[q.internal_node_id] = q;

    })
    db.collection("user").doc(subject_id).set(namedData)
      .then(function() {
        console.log("data saved");
        window.location.replace("https://url.com")
      })
  }

如果您愿意,可以从saveData 返回承诺并在调用者中使用它:

  on_finish: function() {
    saveData(jsPsych.data.get().json()).then(function() {
      window.location.replace("https://url.com");
    });
  },
});

  function saveData(data){
    console.log("trying to save");
    const db = firebase.firestore();
    var data = JSON.parse(data);
    var namedData = {};
    data.forEach(function(q) {
 
      if(q.hasOwnProperty("responses")) {
        q.responses = JSON.parse(q.responses);
      }
      namedData[q.internal_node_id] = q;

    })
    return db.collection("user").doc(subject_id).set(namedData);
  }

【讨论】:

  • 感谢@Frank van Puffelen!这很有帮助!更一般地说,有没有办法在 on_finish 中有两个单独的函数:例如,on_finish: function(){$("#jspsych-content").css({'border-color': "white",'border-style':'solid','border-width':'40px'}) and function(data){data.Trial = trial} 在一个 on_finish 中?我正在努力解决这部分 js。
  • 您可以将代码组合成一个on_finish,如下所示:on_finish: function(){ $("#jspsych-content").css({'border-color': "white",'border-style':'solid','border-width':'40px'; data.Trial = trial; }。这样,当on_finish 被调用时,两者都会被执行。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 1970-01-01
  • 2014-12-21
  • 2015-02-05
相关资源
最近更新 更多