JS SSE 回调不适用于 EventListener
JS SSE callback isn't working with EventListener
我正在使用 JS 库在我的 html 页面上流式传输服务器发送的事件:
<html>
<textarea rows='14' id="value" placeholder="anything you want here"></textarea>
<button type="button" onclick="post(clip)">get</button>
</html>
<script type="text/javascript" src="sse.js"></script>
<script>
url = "http://ac6ba97b046a5dcc677e.elb.us-east-1.amazonaws.com/myapi";
let textArea = document.getElementById("value");
function clip(){
s = textArea.value;
s = s.slice(0, -5);
textArea.value = s;
console.log('hello');
}
function post(callback){
var v = String(textArea.value);
console.log(v);
var source = new SSE(url, {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
payload: v
});
var arr = [];
source.addEventListener('message', function (e) {
arr.push(e.data);
textArea.value = arr.map(el => el || " ").join('');
});
source.stream();
callback();
}
</script>
单击该按钮时,将使用 POST 方法将数据发送到服务器,并使用从服务器接收的数据填充文本框。我想在执行 post()
函数后用 clip()
剪辑文本框中的文本。执行过程必须是这样的:
1. post() logs textArea value
2. source.stream() is executed, textbox populated
3. clip() clips last 5 characters and logs 'hello'
但我却得到了这个:
1. post() logs textArea value
2. clip() clips last 5 characters and logs 'hello'
3. source.stream() is executed, textbox populated
由于某种原因 clip()
在 source.stream()
之前执行,即使在添加回调之后也是如此。
我正在使用的 sse.js 文件。
[编辑] 将 callback()
移动到 'message' 处理程序的末尾后,问题仍然存在:
function post(callback){
var v = String(textArea.value);
console.log(v);
var source = new SSE(url, {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
payload: v
});
var arr = [];
source.addEventListener('message', function (e) {
arr.push(e.data);
textArea.value = arr.map(el => el || " ").join('');
callback();
});
source.stream();
}
有人知道是什么原因造成的吗?
当您的脚本调用 source.stream();
时,它正在执行一个 XMLHttpRequest.send()
操作,默认情况下是异步的。
所以,发生了什么:
- 用户点击,
post()
被调用
- SSE 对象及其事件侦听器已设置
- source.stream() 被调用,它向服务器发送请求。
callback()
(即clip()
)被称为
- 服务器发回响应
- 您的
message
事件处理程序被调用
textArea.value
设置
幸运的是,解决方法很简单:您只希望在收到消息时调用 callback()
。因此,将 callback() 移动到 message
事件处理程序的末尾,而不是 post()
.
的末尾
它会在收到每个消息事件后执行此操作。如果您只希望它在第一个事件之后发生,您将需要实施一些逻辑来跟踪已收到的事件数量。 (如果只有一个消息事件,您应该使用 Ajax 调用,而不是 SSE/EventSource 调用。)
更新:评论中的讨论开始超出您原来问题的范围(答案是,简单地说,“它是异步的,不是同步的”) .但我认为这里值得指出的是,每次用户单击按钮时,您都会设置一个新的 SSE 对象。每个 SSE 对象都有自己专用的 TCP/IP 套接字和自己的侦听器函数。
这(通常)不是一个好主意:而是在您的网络应用程序启动时创建一次 SSE 连接。
而且,尽管您的 SSE
polyfill 库允许使用 POST,但 。如果您只希望应用程序在用户按下按钮时轮询服务器,请考虑从使用 SSE 切换到正常 AJAX.
我正在使用 JS 库在我的 html 页面上流式传输服务器发送的事件:
<html>
<textarea rows='14' id="value" placeholder="anything you want here"></textarea>
<button type="button" onclick="post(clip)">get</button>
</html>
<script type="text/javascript" src="sse.js"></script>
<script>
url = "http://ac6ba97b046a5dcc677e.elb.us-east-1.amazonaws.com/myapi";
let textArea = document.getElementById("value");
function clip(){
s = textArea.value;
s = s.slice(0, -5);
textArea.value = s;
console.log('hello');
}
function post(callback){
var v = String(textArea.value);
console.log(v);
var source = new SSE(url, {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
payload: v
});
var arr = [];
source.addEventListener('message', function (e) {
arr.push(e.data);
textArea.value = arr.map(el => el || " ").join('');
});
source.stream();
callback();
}
</script>
单击该按钮时,将使用 POST 方法将数据发送到服务器,并使用从服务器接收的数据填充文本框。我想在执行 post()
函数后用 clip()
剪辑文本框中的文本。执行过程必须是这样的:
1. post() logs textArea value
2. source.stream() is executed, textbox populated
3. clip() clips last 5 characters and logs 'hello'
但我却得到了这个:
1. post() logs textArea value
2. clip() clips last 5 characters and logs 'hello'
3. source.stream() is executed, textbox populated
由于某种原因 clip()
在 source.stream()
之前执行,即使在添加回调之后也是如此。
我正在使用的 sse.js 文件。
[编辑] 将 callback()
移动到 'message' 处理程序的末尾后,问题仍然存在:
function post(callback){
var v = String(textArea.value);
console.log(v);
var source = new SSE(url, {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
payload: v
});
var arr = [];
source.addEventListener('message', function (e) {
arr.push(e.data);
textArea.value = arr.map(el => el || " ").join('');
callback();
});
source.stream();
}
有人知道是什么原因造成的吗?
当您的脚本调用 source.stream();
时,它正在执行一个 XMLHttpRequest.send()
操作,默认情况下是异步的。
所以,发生了什么:
- 用户点击,
post()
被调用 - SSE 对象及其事件侦听器已设置
- source.stream() 被调用,它向服务器发送请求。
callback()
(即clip()
)被称为- 服务器发回响应
- 您的
message
事件处理程序被调用 textArea.value
设置
幸运的是,解决方法很简单:您只希望在收到消息时调用 callback()
。因此,将 callback() 移动到 message
事件处理程序的末尾,而不是 post()
.
它会在收到每个消息事件后执行此操作。如果您只希望它在第一个事件之后发生,您将需要实施一些逻辑来跟踪已收到的事件数量。 (如果只有一个消息事件,您应该使用 Ajax 调用,而不是 SSE/EventSource 调用。)
更新:评论中的讨论开始超出您原来问题的范围(答案是,简单地说,“它是异步的,不是同步的”) .但我认为这里值得指出的是,每次用户单击按钮时,您都会设置一个新的 SSE 对象。每个 SSE 对象都有自己专用的 TCP/IP 套接字和自己的侦听器函数。 这(通常)不是一个好主意:而是在您的网络应用程序启动时创建一次 SSE 连接。
而且,尽管您的 SSE
polyfill 库允许使用 POST,但