【问题标题】:Getting files over HTTP in Node using promises使用 Promise 在 Node 中通过 HTTP 获取文件
【发布时间】:2018-02-21 00:12:02
【问题描述】:

我编写了这个从 URL 获取文件的函数,并考虑了重定向:

const fetchFile = (url, successCallback, errorCallback) => {
  http.get(url).on('response', function(response) {
    var body = ''
    if((response.statusCode == 301) || (response.statusCode == 302)) {
      console.log('Redirection for ' + url + ' to ' + response.headers.location + ' caught...')
      fetchFile(response.headers.location, successCallback, errorCallback)
      return
    }
    response.on('data', function(chunk) {
      body += chunk
    })
    response.on('end', function() {
      console.log('Completed!')
      successCallback(body)
    })
  })
}

这段代码似乎工作正常,现在我正在尝试重写它以使用没有任何外部模块的承诺,但我没有取得太大进展。我想出了这段代码:

const fetchFileProm = function(url) {
  console.log('In fetchFileProm()');
  return new Promise((resolve, reject) => {
    console.log('In Promise function body')
    var req = http.get(url, (response) => {
      console.log('In Response handler func body');
      var body = ''
      if((response.statusCode == 301) || (response.statusCode == 302)) {
        console.log('Redirection for ' + url + ' to ' + response.headers.location + ' caught...')
        return fetchFileProm(response.headers.location)
      }
      response.on('data', (fragment) => { body += fragment })
      response.on('end', () => resolve(body) )
    })
    req.on('error', function(err) {
      reject(err)
    })
  })
}

当我运行它时,我收到了In Promise function body 消息,但仅此而已。我在这里做错了什么?

【问题讨论】:

  • return fetchFileProm(response.headers.location) 必须是 fetchFileProm(response.headers.location).then(resolve, reject)
  • Node 现在完全支持async/await,你应该尝试一下而不是 Promises。只是说
  • @Btz 看我贴的答案,比较透彻(你对问题中代码所做的修改不够)
  • @JeremyThille 为了使用 async-awaithttp.get() 操作无论如何都必须“承诺”

标签: javascript node.js http promise es6-promise


【解决方案1】:

当您处于异步操作中时,常规的 return 不起作用,因此当您执行 return fetchFileProm(response.headers.location) 时,没有任何东西可以处理该返回,也没有任何东西可以解决您的承诺。

你需要做的是递归地将回调传递给下一个异步操作:

      ...
      var req = http.get(url, (response) => {
        console.log('In Response handler func body');
        var body = ''
        if((response.statusCode == 301) || (response.statusCode == 302)) {
          console.log('Redirection for ' + url + ' to ' + response.headers.location + ' caught...')
          fetchFileProm(response.headers.location).then(resolve, reject);
        } else {
          response.on('data', (fragment) => { body += fragment })
          response.on('end', () => resolve(body) )
        }
      })
      ...

【讨论】:

  • 不幸的是,这个修复并没有解决问题。我仍然没有得到比In Promise function body 消息更进一步的信息。
  • @Btz 如果您甚至没有收到In Response handler func body,那么您的第一个问题就是您的http.get() 电话。即使你解决了这个问题,我建议的修改仍然是重定向工作所必需的。
  • 当然,重点。我只是不知道需要为 http.get() 修复什么。基于回调的版本运行良好。
  • @Btz 是的,恐怕我也看不出有什么问题
  • 对,我做了更多的实验。如果 url 用于非重定向文件,则一切正常。但是,如果 url 被重定向,那么由于某种原因,它会立即成功,并将重定向消息(“您正在被重定向到 example.com/randomUrl")作为接收到的数据。所以,就像你建议的那样,问题出在调用的结构和处理重定向的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2013-08-31
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 2013-10-28
相关资源
最近更新 更多