JavaScript向PHP传OneSignal userId写库时值为NULL问题
问题诊断
两个异常均为JavaScript异步执行时序与变量作用域导致的基础语法问题,和OneSignal接口逻辑无关:
- 替换为
theuserid时代码不执行:你两次声明的var theuserid都属于.then()回调函数内的局部变量,写在Promise链外部的跳转语句无法访问该变量,执行时会直接抛出ReferenceError: theuserid is not defined错误,中断后续逻辑,因此跳转不会触发。 - 使用
useragentid时传值为NULL:OneSignal.getUserId()是异步Promise方法,你放在Promise链外部的跳转语句不会等待Promise执行完成、给useragentid赋值就会立刻运行,此时useragentid还未被赋值,拼接到URL中传递给后端时自然是空值/NULL。 - 额外冗余问题:你在第二个
.then()回调中重新声明var theuserid = OneSignalUserSubscription(useragentid)属于无效代码,该变量后续没有被任何逻辑引用。
修复方法
所有依赖getUserId()返回值的逻辑(包括页面跳转、用户ID上报),必须放到Promise链的.then()回调内部执行,确保拿到有效userId后再运行对应逻辑,核心修正代码如下:
//Secondly this will check when subscription changed OneSignal.push(function() { OneSignal.on('subscriptionChange', function (isSubscribed) { if(isSubscribed==true){ OneSignal.getUserId().then(function(userId) { // 拿到有效userId后再执行所有依赖该值的操作 OneSignalUserSubscription(userId); window.location.href = "sub_post.php?userId=" + userId + "&sponsor=josh"; document.getElementById('successtext').style.display = 'block'; document.getElementById('unsubscribe').style.display = ''; document.getElementById('subscribe').style.display = 'none'; }); } else if(isSubscribed==false){ OneSignal.getUserId().then(function(userId) { // 退订场景下依赖userId的逻辑同样需要写在该then回调内 let useragentid = userId; }); document.getElementById('unsubscribe').style.display = 'none'; document.getElementById('subscribe').style.display = ''; } else{ console.log('Unable to process the request'); } }); });
注意:JavaScript异步回调不会阻塞外部同步代码执行,所有依赖异步接口返回值的逻辑,都必须写在对应的回调函数内部,写在外部的代码会在异步接口返回前就执行完毕,拿不到预期的返回值。
内容的提问来源于stack exchange,提问作者Randy Thomas
相关产品推荐
相关产品推荐

