如here所示,使用docker扩展API,您可以流式传输容器的输出,但当我尝试存储每行日志的data.stdout字符串时,它只是不断变化,就像它是一个对象引用一样...我甚至尝试使用data.stdout.slice()
复制字符串或使用JSON.stringify(data.stdout)
在JSON中转换它,以便获得具有不同引用的新对象,但不起作用:/
...
const[logs,setLogs]=useState<string[]>([]);
...
ddClient.docker.cli.exec('logs', ['-f', data.Id], {
stream: {
onOutput(data): void {
console.log(data.stdout);
setLogs([...logs, data.stdout]);
},
onError(error: unknown): void {
ddClient.desktopUI.toast.error('An error occurred');
console.log(error);
},
onClose(exitCode) {
console.log("onClose with exit code " + exitCode);
},
splitOutputLines: true,
},
});
1条答案
按热度按时间qxgroojn1#
Docker扩展团队成员。我不是ReactMaven,所以我的解释可能是错误的,但我认为这个问题与React如何工作有关。
在你的组件中,调用
ddClient.docker.cli.exec('logs', ['-f'], ...)
会在每次从后端流来一些数据时更新logs
状态的值。这个更新会使组件重新呈现并再次执行所有的东西。因此,你会有很多对ddClient.docker.cli.exec
的调用被执行。而且它会呈指数级增长。问题在于,由于存在许多
ddClient.docker.cli.exec
调用,因此也存在同样多的对setLogs
的调用同时更新logs
的状态,但是扩展logs
的值并不能保证该值是最后一次设置的。您可以尝试以下方法来移除Docker Extensions SDK。它做的是完全相同的事情:它每400ms更新
setTimeout
回调内的content
状态。由于setTimeout
在每次渲染时运行并且从不清除,因此将同时存在content
的许多更新。你会看到奇怪的结果:)
以下是如何执行您要执行的操作:
这里发生的是
ddClient.docker.cli.exec
的调用是在useEffect
中完成的logs
,而是向setLogs
函数提供回调,以确保将包含在data.stdout
中的最新值添加到状态的最新版本中,要尝试使用该命令,请确保更新了logs命令的参数数组。