【问题标题】:ES6 async/await in classes类中的 ES6 异步/等待
【发布时间】:2018-03-19 11:09:02
【问题描述】:

我正在尝试创建一个将发送发布请求(登录)、保存 cookie 并将该 cookie 用于其他操作(例如下载文件)的类。

我创建了一个本地服务器,它将接收一个包含用户和密码的 post http 方法和一个名为 /download 的路由器,只有在用户登录时才能访问,否则它将返回 you need to log in

问题: 这是我班级的原型(之前):

const request = require('request-promise-native')

class ImageDownloader {
  constructor(username = null, password = null) {
    this.username = username
    this.password = password
    this.cookie = request.jar()

    this.init()
  }

  init() {
    // login and get the cookie
  }

  download() {
    // needs the cookie
  }

  query() {
    // needs the cookie
  }
}

正如您在上面的代码中看到的,我需要两个操作的 cookie,即 downloadquery 所以我想创建一个 init 方法来执行初始操作,例如登录并调用它在构造函数中,因此它将被初始化并将cookie放在变量this.cookie上以在任何地方使用,但它不起作用,似乎在所有其他方法之后都会调用init

const request = require('request-promise-native')

class ImageDownloader {
  constructor(username = null, password = null) {
    this.username = username
    this.password = password
    this.cookie = request.jar()

    this.init()
  }

  async init() {
    await request({
      uri: 'http://localhost/login',
      jar: this.cookie,
      method: 'post',
      formData: {
        'username': 'admin',
        'password': 'admin'
      }
    }).catch(e => console.error(e))
  }

  async download() {
    await request({
      uri: 'http://localhost/download/image.jpg',
      jar: this.cookie
    })
    .then(b => console.log(b))
    .catch(e => console.error(e))
  }

  query() {
    // ...
  }
}

const downloader = new ImageDownloader
downloader.download()

返回给我,我需要登录(服务器响应)...但是如果我进行此更改,它会起作用:

async download() {
  await init() // <<<<<<<<<<<<
  await request({
    uri: 'http://localhost/download/image.jpg',
    jar: this.cookie
  })
  .then(b => console.log(b))
  .catch(e => console.error(e))
}

只有当我在 download 方法中调用 init 时它才有效。

如果我将console.log(this.cookie) 放入download,它会返回一个空的CookieJar,如果我将它放入init,它将返回正确的cookie,但它会出现在之后执行即使我在调用 download 之前在构造函数上调用了它,也要下载。

如何解决?非常感谢。

@编辑

我做了 @agm1984@Jaromanda X 告诉我的更改,但它仍然不起作用:(

const request = require('request-promise-native')

class ImageDownloader {
  constructor(username = null, password = null) {
    this.username = username
    this.password = password
    this.cookie = request.jar()

    this.init().catch(e => console.error(e))
  }

  async init() {
    return await request({
      uri: 'http://localhost/login',
      jar: this.cookie,
      method: 'post',
      formData: {
        'username': 'admin',
        'password': 'admin'
      }
    })
  }

  async download() {
    return await request({
      uri: 'http://localhost/download/image.jpg',
      jar: this.cookie
    })
  }

  query() {
    // ...
  }
}

const downloader = new ImageDownloader
downloader.download()
          .then(b => console.log(b))
          .catch(e => console.error(e))

但话又说回来......除非我在download 中调用init,否则它不起作用。

【问题讨论】:

  • @JaromandaX 我不明白为什么我会返回任何内容,因为 initdownload 内部的操作不需要在任何地方共享,request-promise-native 会将 jar 放入this.cookie 对我来说(我需要什么),但问题是事情的运行顺序。在download 中添加await init() 的行为就像“我必须等待init 完成然后继续”(类似这样),但是当我在构造函数中调用this.init 时,我虽然不需要它.
  • 对不起,是的,我看错了你的代码
  • 正如我所说,我误读了您的代码,忽略了我的更改:p - 因为我搞砸了 我的 对 async/await 的了解:p跨度>
  • 没关系,您试图提供帮助,我完全理解您的意思。还是谢谢你。
  • 现在的问题是download 不会等待init

标签: javascript node.js ecmascript-6 async-await es6-promise


【解决方案1】:

这里的问题是init 是异步的。像这样使用它:

const downloader = new ImageDownloader;
downloader.download();

download 函数正在执行,而init 仍未完成。

我不会在构造函数中调用 init 方法。我会做的是这样的:

1- 从构造函数中删除初始化调用。
2- 使用这样的类:

const downloader = new ImageDownloader();
downloader.init()
  .then(() => downloader.download());

如果你在 async 函数中调用 init,你可以这样做:

await downloader.init();
const result = await downloader.download();

【讨论】:

    猜你喜欢
    • 2018-07-16
    • 2017-09-14
    • 1970-01-01
    • 2020-03-27
    • 2021-10-22
    • 1970-01-01
    • 2023-03-12
    • 2017-06-19
    • 2016-07-07
    相关资源
    最近更新 更多