【问题标题】:NodeJS - Calling Fetch in a Function hangs the consoleNodeJS - 在函数中调用 Fetch 会挂起控制台
【发布时间】:2020-12-15 20:47:54
【问题描述】:

我的 React 客户端出现问题,因此我使用更简单的单文件节点程序重现了该错误。在反应客户端中,我没有得到任何数据。使用 Postman,我可以执行“获取”并检索 JSON 数据。

有人可以帮我让它在不挂起的情况下运行吗?

我最近在服务器端 gettranslations 中做了一个类似的函数,这样我就可以从一个函数中调用 MongoDB。 (NodeJS ASync call of MongoClient GetData routine)。我想我遵循的模式与我在那里的答案相同。

我考虑过使用“等待”,但我不在异步函数中。而且我刚才提到的上述示例中不需要“等待”,因为该函数使用“.then”模式。

部分代码:

const fetch = require("node-fetch");

function getDBLanguagesAndConvertToDataTable(fromLanguage, toLanguage) { 
  // TODO implement from/to Language in URL below  
  console.log("Function: " + getFormattedTime())
  return fetch('http://localhost:3001/api/gettranslations/en-US/es-MX', {
                  method: 'GET',
                  headers: {
                    'Accept': 'application/json'
                  }
    })
  .then(function(data) {
     // do something with the data 
     console.log("Status:", data.status)
     console.log("data from DB:")
     console.log(JSON.stringify(data)) 
     console.log("data.body:")
     console.log(JSON.stringify(data.json())) 
     // I call another function here to reshape the data, 
     // but even with that commented out, same issue. 
     return data.json() 
  })
  .catch(function(err){
     console.log("Error:" + err)
     throw new Error(err) 
  })
}


console.log("------- Test with Fetch/Get/FromWebservice -------")
console.log(getFormattedTime())
var fromLanguage = 'en-US'
var toLanguage = 'es-MX'

getDBLanguagesAndConvertToDataTable(fromLanguage, toLanguage)
    .then(function (dataTable) {
        console.log(getFormattedTime, " Back from call fetch")
        var strDataTable = JSON.stringify(dataTable, null, 3);  
        console.log("ReactTables(): Resulting DataTable=")
        console.log(strDataTable) 
        console.log(getFormattedTime(), "The end of tests ")    

})

我运行“node test.js”。它显示以下内容并挂起。我必须做 CNTL-Break 来结束它。

------- Test with Fetch/Get/FromWebservice -------
2020-08-26-20-43-08
Function: 2020-08-26-20-43-08

第 2 部分 - 添加捕获后

修改后的代码:

function getDBLanguagesAndConvertToDataTable(fromLanguage, toLanguage) { 
  // TODO implement from/to Language in URL below  
  console.log("Function: " + getFormattedTime())
  return fetch('http://localhost:3001/api/gettranslations/en-US/es-MX', {
                  method: 'GET',
                  headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                  }
    })
  .then(function(data) {
     // do something with the data 
     console.log("Status:", data.status)
     console.log("data from Fetch:")
     console.log(JSON.stringify(data)) 
     console.log("data.json():")
     console.log(JSON.stringify(data.json())) 
 
     //var tmpDataTable = convertMongoLanguagesToDataTable(data.json())
     //return tmpDataTable
     return data.json() 
  })
  .catch(function(err){
     console.log("Fetch Error:" + err)
     throw new Error(err) 
  })
}

/*
console.log("------- Test with variable data-------------")
console.log(getFormattedTime())
dataTable = convertMongoLanguagesToDataTable(dbGetResults) 
var strDataTable = JSON.stringify(dataTable, null, 3);  
console.log("Resulting DataTable=")
console.log(strDataTable) 
console.log("\n\n")
*/ 

console.log("------- Test with Fetch/Get/FromWebservice -------")
console.log(getFormattedTime())
var fromLanguage = 'en-US'
var toLanguage = 'es-MX'

getDBLanguagesAndConvertToDataTable(fromLanguage, toLanguage)
    .then(function (dataTable) {
        console.log(getFormattedTime, " Back from call fetch")
        var strDataTable = JSON.stringify(dataTable, null, 3);  
        console.log("ReactTables(): Resulting DataTable=")
        console.log(strDataTable) 
        console.log(getFormattedTime(), "The end of tests ")    
    .catch(function (err){
        console.log("call function getDBLanguagesAndConvertToDataTable error:", 
                     getFormattedTime(), "The end of tests ")    
        
    })
})

输出:

------- Test with Fetch/Get/FromWebservice -------
2020-8-26-21-31-5
Function: 2020-8-26-21-31-5
Status: 200
data from Fetch:
{"size":0,"timeout":0}
data.body:
{}
Fetch Error:TypeError: body used already for: http://localhost:3001/api/gettranslations/en-US/es-MX
(node:38732) UnhandledPromiseRejectionWarning: Error: TypeError: body used already for: http://localhost:3001/api/gettranslations/en-US/es-MX
    at E:\GitHub\NealWalters\KyleShedCompanyPOC\shedco-backend\test_convert_languages_to_data_table.js:144:12
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:38732) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:38732) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

【问题讨论】:

  • 您对fetch() 的呼叫显然没有解决或拒绝。你必须弄清楚为什么会这样。它没有挂。它只是在等待来自服务器的响应。您还应该在对getDBLanguagesAndConvertToDataTable() 的调用中添加.catch(),这样您就可以知道该级别是否存在错误。如果这是您的服务器,则在服务器中进行调试以查看它对这个请求做了什么。
  • 仅供参考,在 GET 请求上设置 Content-Type 没有意义,因为请求没有内容(内容类型适用的请求正文为空)。
  • @jfriend00 谢谢,请参阅上面我修改后的“第 2 部分”。我添加了捕获;它不是挂起的,而是我开始谷歌搜索的新的神秘错误。 (我可以看到 3001 网络服务工作正常;它在另一个窗口中有一些 console.logs)。
  • 好的,这是一个流,我无法访问它两次,再次调整代码。 github.com/node-fetch/node-fetch/issues/533
  • 明白了,你当然是对的!我将发布我的修复作为答案。

标签: node.js freeze node-fetch


【解决方案1】:

根据上面的@jfriend00 评论,我需要在每个 .then 语句上添加 .catch。

一旦我得到了捕获,我就得到了一个错误,因为我试图访问流两次,所以现在我只是注释掉了从 fetch 返回的“data”变量上的额外 console.logs。 (发现此处描述的错误: https://github.com/node-fetch/node-fetch/issues/533)

那时,我可以在控制台的 web 服务中看到我的 JSON,并且不再挂起!

修改后的代码:

function getDBLanguagesAndConvertToDataTable(fromLanguage, toLanguage) { 
  // TODO implement from/to Language in URL below  
  console.log("Function: " + getFormattedTime())
  return fetch('http://localhost:3001/api/gettranslations/en-US/es-MX', {
                  method: 'GET',
                  headers: {
                    'Accept': 'application/json'
                  }
    })
  .then(function(data) {
     // do something with the data 
     /*
     console.log("Status:", data.status)
     console.log("data from Fetch:")
     console.log(JSON.stringify(data)) 
     console.log("data.json():")
     console.log(JSON.stringify(data.json())) 
     */ 
 
     //var tmpDataTable = convertMongoLanguagesToDataTable(data.json())
     //return tmpDataTable
     return data.json() 
  })
  .catch(function(err){
     console.log("Fetch Error:" + err)
     throw new Error(err) 
  })
}

/*
console.log("------- Test with variable data-------------")
console.log(getFormattedTime())
dataTable = convertMongoLanguagesToDataTable(dbGetResults) 
var strDataTable = JSON.stringify(dataTable, null, 3);  
console.log("Resulting DataTable=")
console.log(strDataTable) 
console.log("\n\n")
*/ 

console.log("------- Test with Fetch/Get/FromWebservice -------")
console.log(getFormattedTime())
var fromLanguage = 'en-US'
var toLanguage = 'es-MX'

getDBLanguagesAndConvertToDataTable(fromLanguage, toLanguage)
    .then(function (dataTable) {
        console.log(getFormattedTime, " Back from call fetch")
        var strDataTable = JSON.stringify(dataTable, null, 3);  
        console.log("ReactTables(): Resulting DataTable=")
        console.log(strDataTable) 
        console.log(getFormattedTime(), "The end of tests ")    
    })
    .catch(function (err){
        console.log("call function getDBLanguagesAndConvertToDataTable error:", 
                     getFormattedTime(), "The end of tests ")    
        
    })

【讨论】:

    猜你喜欢
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 2012-02-21
    相关资源
    最近更新 更多