如何使用 Promise 和 node.js 正确检查和记录 http 状态代码?

Posted

技术标签:

【中文标题】如何使用 Promise 和 node.js 正确检查和记录 http 状态代码?【英文标题】:How to properly check and log http status code using promises and node.js? 【发布时间】:2018-08-03 02:37:09 【问题描述】:

我是 javascript 新手,对 node.js 框架非常陌生,几天前才开始使用它。如果我的代码是荒谬的,我深表歉意,承诺和回调的整个想法仍然深入人心。话虽如此,我的问题是以下我试图弄清楚对网站的某些请求是否成功或导致错误的范围他们的状态码响应。我正在处理一系列网站,到目前为止我所做的工作如下,但是我在安装了 node.js 的本地计算机上得到了TypeError: Cannot read property 'then' of undefined,但不知道为什么。

const sample = [
    'http://www.google.com/',
    'http://www.spotify.com/us/',
    'http://twitter.com/',
    'http://google.com/nothing'
]

const http = require('http')

const getStatusCodeResult = (website) => 

    http.get(website, (res) => 
        return new Promise((resolve, reject) => 
            setTimeout(() => 
                let statusCode = res.statusCode
                error = statusCode >= 400 && statusCode <= 500 ? `error: $website`: null
                if (error) 
                    reject(error)
                    
                 else if (statusCode >= 200 && statusCode <= 300) 
                    resolve(`Success: $website`)
                
            , 0)
        )
    )

// LOOP PROMISES
const getAllStatusCodeResult = (websites) => 
    websites.forEach((website) => 
        getStatusCodeResult(website)
            .then((result) => 
                console.log(result)
            )
            .catch(error => 
                console.log('error', error)
            )
    )

getAllStatusCodeResult(sample)

理想情况下,我希望将结果打印为下面的示例,但现在我只是使用console.log 来确定代码是否有效。

   // Example Printout
   
      success: ['https://www.google.com/', 'https://www.spotify.com/us/', 
      'https://twitter.com /' ],
      error: [''http://google.com/nothing']
    

【问题讨论】:

【参考方案1】:

你混淆了前两行。为您获取返回值的 new Promise 包装器需要位于外部,而 http.get 调用应位于其执行器回调中。你也不需要那个超时:

function getStatusCodeResult(website) 
    return new Promise((resolve, reject) => 
        http.get(website, (res) => 
            let statusCode = res.statusCode,
                error = statusCode >= 400 && statusCode <= 500 ? `error: $website`: null
            if (error) 
                reject(error)
             else if (statusCode >= 200 && statusCode <= 300) 
                resolve(`Success: $website`)
            
        )
    )

【讨论】:

太棒了,你能解释一下为什么承诺包装http.get 是它一直使用的方式你用承诺包装引用环境吗?另外,你有没有机会知道为什么我只收到error error: http://google.com/nothing Success: http://www.google.com/ 而不是其他网站。 是的,您总是将异步函数包装在 new Promise 构造函数中。你解决和拒绝的方式通常不同 如果你没有从其他承诺中得到任何东西,很可能响应既不是 400 @Bergi 使用util.promisify() 添加解决方案对我有好处吗?还是我不应该打扰? @Bergi 你认为我应该发布一个不同的问题,关于不记录示例数组中的所有站点只记录http://google.com/nothing http://www.google.com/【参考方案2】:

使用util.promisify(),您可以将http.get()转换为基于promise的异步方法,但首先需要做一些准备,因为它不遵循callback(error, response) ... 的约定:

const http = require('http')
const  promisify  = require('util')

// define a custom promisified version of `http.get()`
http.get[promisify.custom] = (options) => new Promise(resolve => 
  http.get(options, resolve)
);

// convert callback to promise
const httpGet = promisify(http.get)

async function getStatusCodeResult(website) 
  const res = await httpGet(website)
  const status = res.statusCode
  const message = `$http.STATUS_CODES[status]: $website`

  if (status >= 400) 
    throw message
   else 
    return message
  

此外,您可以使用http.STATUS_CODES 为每个可能的statusCode 获取适当的消息,而不是返回模糊的ErrorSuccess

【讨论】:

我想知道,http.get[promisify.custom] 不应该已经是节点中的本机了吗? @Bergi 我检查了,它没有定义。

以上是关于如何使用 Promise 和 node.js 正确检查和记录 http 状态代码?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Node.Js 和 Promises,你如何返回一个已经实现的 Promise? [复制]

如何使用 promise 将数组从我的模块返回到我的 API?异步函数和承诺 - Node.js

如何确保 Node.js 中的这些函数链按顺序执行(使用 Promise)?

如何在 node.js 中将函数与 Promise 同步

我们如何在(Node.js 8. 目前)上的 readline.on 函数下使用 promise

如何在 node.js 中实际使用 Q Promise?