【发布时间】:2022-01-26 12:45:12
【问题描述】:
我是 JS 新手,我的任务是实现将用户点击事件(点击按钮、电子邮件输入字段)发送给网络工作者的功能。工作人员必须将数据收集到 5 个项目的批次中,并将其发送到服务器(使用 POST /analytics/user)端点。问题是我不明白如何收集用户点击并将它们发送到我搜索文档但没有提到批次的 5 个项目的批次中。请问你能帮帮我吗?我的网站有3个按钮,其中2个没有任何事件监听器,最后一个用于提交邮件,如下图:
/analytics/来自路由的用户端点代码:
router.post('/user', async function (req, res) {
const payload = req.body;
try {
let data;
try {
data = await FileStorage.readJsonFile('user-analytics.json');
} catch (e) {
data = [];
}
data.push({timestamp: Date.now(), data: payload});
await FileStorage.writeFile('user-analytics.json', data);
await res.json({success: true})
} catch (e) {
console.log(e);
res.status(500).send('Internal error');
}
});
如果我应该添加更多关于某事的信息,请告诉我。
编辑:
我编写了发送按钮点击的函数,然后工作人员应该将数据发送到服务器,但现在的问题是我不能将消息推送到网络工作人员到一个数组,它只推送第一条消息..
向网络工作者发送用户点击的功能:
export const sendUserClicksToWorker = () => {
const allButtonsToStore = document.getElementsByClassName("app-section__button");
const inputField = document.getElementsByClassName("form-input")
let reason = [];
//for loop for pushing clicks from buttonts to the array
for (let x = 0; x < allButtonsToStore.length; x++) {
allButtonsToStore[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
console.log(this.textContent)
});
}
//for loop for pushing click from email input field to the array
for (let x = 0; x < inputField.length; x++) {
inputField[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
console.log(this.textContent)
});
}
}
向服务器发送数据的函数:
export const sendButtonClicksToServer = (dataToSend) => {
sendHttpRequest('POST', 'http://localhost:8080/analytics/user', {
dataToSend
}).then(responseData => {
return responseData
//console.log(responseData);
}).catch(err => {
console.log(err, err.data)
window.alert(err.data.error)
})
}
在主 js 文件中:
if (window.Worker) {
const url = new URL('./scripts/worker.js', import.meta.url);
const worker = new Worker(url);
const allButtonsToStore = document.getElementsByClassName("app-section__button");
const inputField = document.getElementsByClassName("form-input")
//for loop for pushing clicks from buttonts to the array
for (let x = 0; x < allButtonsToStore.length; x++) {
allButtonsToStore[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
//console.log(this.textContent)
});
}
//for loop for pushing click from email input field to the array
for (let x = 0; x < inputField.length; x++) {
inputField[x].addEventListener("click", function () {
worker.postMessage(this.textContent)
// console.log(this.textContent)
});
}
worker.onmessage = e => {
console.log(e.data)
sendButtonClicksToServer(e.data);
}
worker.onerror = error => {
console.log(error.message)
}
}
还有 worker.js:
let data = []
onmessage = function (e) {
console.log('Data Received: ',e.data)
let receivedButtonClicks = e.data
// data.push(receivedButtonClicks)
// if (data.length > 4) {
// postMessage(data)
// data.length = 0;
// console.log('Data received!')
// console.log(data)
// }
for ( let i = 0 ; i< 5;i++){
data[i].push(receivedButtonClicks)
}
console.log('blabla',data)
}
现在我 100% 不明白问题出在哪里以及如何解决??..
-
出于好奇,您可以在不使用工人的情况下这样做吗?
-
是的,它是,我应该和一个网络工作者一起做.. 4 小时我已经尝试在一个数组中推送到达网络工作者的消息,我得到的只是一个包含 5 个类似项目的数组: (
-
部分问题是您在
onmessage
函数中声明data
,每次收到消息时都会创建一个新的空列表。试着把它放在onmessage
上面(在全局范围内),看看修复了多少 -
我在上面声明了它并且有同样的问题:(
-
你想写
data.push(...)
,而不是data[i].push(...)
--data[i]
引用了data
中不存在的元素。此外,我会将data
重命名为batch
或类似名称,只是为了保持理智。更好的变量名称将使变量的含义更清晰,并帮助您编写自己的代码。