首页 > 解决方案 > NodeJS Express 模块错误:TypeError:无法读取未定义的属性“已完成”

问题描述

我正在尝试制作一个 api,它可以从您输入的任何单词中获取来自站点的文本。我使用 selenium 加载网站并发送文本,但我无法将其发回。这是我的代码:

app.get("/search/:data", function(req, res){
async function extraction(){
    driver.findElement(By.xpath("(//input[@type='text'])[6]")).clear();
    driver.findElement(By.xpath("(//input[@type='text'])[6]")).sendKeys(req.params.data.replaceAll('_', ' '));
    console.log(`Sent keys ${req.params.data} from ${req.ip}.`);
    setTimeout(function () {
            driver.findElement(By.xpath("/html/body/div[8]/div[1]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[2]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[3]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[4]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[5]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[6]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[7]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[8]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[9]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[10]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[11]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[12]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[13]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[14]/div")).getText().then(res.write);
            driver.findElement(By.xpath("/html/body/div[8]/div[15]/div")).getText().then(res.write);
            res.end();
        }, 10000);

}
extraction();
});

当我用 console.log 替换 res.write 时,它​​会记录它,但我无法让它发送。我是 Javascript 的新手,所以我还在学习,我花了几个小时寻找答案,但无法让它发挥作用。

错误信息:

  if (msg.finished) {
          ^

TypeError: Cannot read property 'finished' of undefined
    at write_ (node:_http_outgoing:727:11)
    at write (node:_http_outgoing:687:15)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)```

标签: javascriptnode.jsapiseleniumexpress

解决方案


似乎您不能res.write作为回调传递,因为它丢失了响应对象的跟踪,它试图从中读取finished属性。

尝试创建一个调用的自定义回调res.write,例如

const writeToResponse = res.write.bind(res);

driver.findElement(By.xpath("/html/body/div[8]/div[1]/div")).getText().then(writeToResponse);
// similarly the rest of the code

除了上述修复之外,我发现当前结构中的代码存在更多潜在问题:据我所知,.getText返回一个 Promise,所以我们在这里处理异步代码。

  1. res.end()无需等待前面的说明完成即可拨打电话。这很可能会导致以下错误
Error [ERR_STREAM_WRITE_AFTER_END]: write after end

您可能应该使用Promise.all等待每个电话或所有电话

  1. 如果将文本写入响应的顺序很重要,那么您应该在执行下一个调用之前等待每个调用,否则所有 15 个调用并行执行并与将数据写入响应竞争。

推荐阅读