You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在jsPsych 7.2中实现条件分支逻辑的问题求助

jsPsych 7.2 条件分支逻辑修复方案

你的代码存在两个核心问题,导致问卷无论第一个选项选什么都会直接结束:

  1. 提前固定了timeline的执行顺序:你在定义完「是否吃肉」的问题后,直接把「是否吃乳制品」和感谢页面都加入了timeline,这意味着这些环节会强制按顺序执行,完全忽略了你的分支逻辑。
  2. response索引判断+动态添加trial的逻辑混乱:jsPsychHtmlButtonResponse的response返回选项的索引(从0开始),你对分支条件的判断不符合选项顺序;同时在on_finish里动态push trial的方式会打乱timeline的执行流程,导致后续环节顺序混乱。

正确实现方案(官方推荐的条件分支方式)

使用jsPsychConditional插件来控制分支流程,这是jsPsych官方设计的条件逻辑控制工具,能避免手动修改timeline带来的问题:

// 定义所有问卷组件
var meatYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you eat meat?',
  choices: ['No', 'Yes'],
  data: {task: 'meat_check'}
};

var rawMeatYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you ever eat it raw?',
  choices: ['No', 'Yes']
};

var dairyYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you eat dairy?',
  choices: ['No', 'Yes'],
  data: {task: 'dairy_check'}
};

var yoghurtLike = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you like yoghurt?',
  choices: ['No', 'Yes']
};

var thanks = {
  type: jsPsychInstructions,
  pages: ['Thanks for your time']
};

// 构建主timeline
var timeline = [];

// 第一步:询问是否吃肉
timeline.push(meatYN);

// 分支1:选择「是」(response=1)→ 询问生肉问题→结束
timeline.push({
  type: jsPsychConditional,
  conditional_function: function(){
    // 检查上一个trial的response是否为1(对应Yes选项)
    return jsPsych.data.get().last(1).values()[0].response === 1;
  },
  timeline: [rawMeatYN, thanks]
});

// 分支2:选择「否」(response=0)→ 进入乳制品分支
timeline.push({
  type: jsPsychConditional,
  conditional_function: function(){
    return jsPsych.data.get().last(1).values()[0].response === 0;
  },
  timeline: [
    dairyYN,
    // 乳制品分支:选「是」(response=1)→ 询问酸奶问题
    {
      type: jsPsychConditional,
      conditional_function: function(){
        return jsPsych.data.get().last(1).values()[0].response === 1;
      },
      timeline: [yoghurtLike]
    },
    // 无论乳制品选什么,最后都显示感谢
    thanks
  ]
});

// 启动问卷
jsPsych.run(timeline);

简化版实现(无需插件)

如果不想使用插件,可以给每个需要条件执行的trial添加conditional属性,通过判断上一个trial的数据来决定是否执行当前trial:

// 定义所有问卷组件
var meatYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you eat meat?',
  choices: ['No', 'Yes'],
  data: {task: 'meat_check'}
};

var rawMeatYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you ever eat it raw?',
  choices: ['No', 'Yes']
};

var dairyYN = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you eat dairy?',
  choices: ['No', 'Yes'],
  data: {task: 'dairy_check'}
};

var yoghurtLike = {
  type: jsPsychHtmlButtonResponse,
  stimulus: 'Do you like yoghurt?',
  choices: ['No', 'Yes']
};

var thanks = {
  type: jsPsychInstructions,
  pages: ['Thanks for your time']
};

var timeline = [];

timeline.push(meatYN);

// 生肉问题:仅当选择吃肉(response=1)时执行
timeline.push({
  ...rawMeatYN,
  conditional: function(){
    return jsPsych.data.get().last(1).values()[0].response === 1;
  }
});

// 乳制品问题:仅当选择不吃肉(response=0)时执行
timeline.push({
  ...dairyYN,
  conditional: function(){
    return jsPsych.data.get().last(1).values()[0].response === 0;
  }
});

// 酸奶问题:仅当选择吃乳制品(response=1)时执行
timeline.push({
  ...yoghurtLike,
  conditional: function(){
    var lastData = jsPsych.data.get().last(1).values()[0];
    return lastData.task === 'dairy_check' && lastData.response === 1;
  }
});

// 最后统一显示感谢页面
timeline.push(thanks);

jsPsych.run(timeline);

原代码失败原因说明

你原代码中,在定义完meatYN后直接将dairyYN和thanks加入了timeline,这导致这两个环节会强制执行,完全覆盖了你在on_finish里添加的分支逻辑。用户在选完第一个问题后,会直接进入乳制品问题,然后到感谢页面,此时你动态添加的raw和thanks会在整个流程的最后执行,但用户已经看到感谢页面,误以为问卷结束,所以出现“无论选什么都直接结束”的问题。

内容的提问来源于stack exchange,提问作者Á L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 14:54:52