ES6异步/等待类

时间:2017-10-07 23:39:47

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

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

我创建了一个本地服务器,它将接收一个带有用户和密码的post http方法,以及一个名为/download的路由器,只有在用户登录时才会被访问,否则它将返回{{1 }}

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

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 } } download操作的cookie,所以我想创建一个query方法来执行初始操作作为登录并在构造函数中调用它,因此它将被初始化并将cookie放在变量init上以便在任何地方使用,但它不起作用,似乎每次都调用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)) } 方法中调用init时才有效。

如果我将download放入console.log(this.cookie),则会返回一个空的download,如果我将其放在CookieJar中,它将返回正确的Cookie,但它会显示 AFTER 执行下载,即使我在调用init之前在构造函数上调用了它。

如何解决?非常感谢你。

@edit

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

download

但是又一次......除非我在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)) 内拨打init,否则它无效。

1 个答案:

答案 0 :(得分:1)

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

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

正在执行download功能,init尚未完成。

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

1-从构造函数中删除init调用 2-使用这样的类:

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

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

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