javascript 类中的 ES6 异步/等待
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46626144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ES6 async/await in classes
提问by vajehu
I'm trying to create a class that will send a post request (login), save the cookie and use that cookie for other operations such as download a file.
我正在尝试创建一个类,该类将发送发布请求(登录)、保存 cookie 并将该 cookie 用于其他操作,例如下载文件。
I created a local server that that will receive a post http method with user and password in it and a router called /downloadthat will only be accessed if the user is logged in, otherwise it will return you need to log in.
我创建了一个本地服务器,它将接收一个带有用户和密码的 post http 方法和一个被调用的路由器/download,只有在用户登录时才能访问它,否则它将返回you need to log in.
The problem: This is the prototype of my class (before hand):
问题:这是我班级的原型(事先):
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
}
}
As you can see in the code above I need the cookie for two operations that is downloadand queryso I though about creating an initmethod that will do the initial operations such as login and call it right in the constructor so it will be initialized and put the cookie on the variable this.cookieto use everywhere, but it doesn't work, it seems that initis being called after every other method.
正如您在上面的代码中看到的,我需要两个操作的 cookie download,query所以我想创建一个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()
It's returning to me that I need to log in (server response)... BUT it works if I do this change:
它返回给我,我需要登录(服务器响应)......但如果我进行此更改,它会起作用:
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))
}
It only works if I call initin the downloadmethod.
它仅在我调用init该download方法时才有效。
If I put console.log(this.cookie)in downloadit returns an empty CookieJarand if I put the same in initit will return the right cookie but it appears AFTERthe execution of download even tho I called it on the constructor before calling download.
如果我把console.log(this.cookie)在download它返回一个空的CookieJar,如果我把同样的init它会返回正确的Cookie,但它出现后下载的执行甚至寿我把它叫做在构造函数调用之前download。
How to solve that? Thank you very much.
如何解决?非常感谢你。
@edit
@编辑
I made the changes that @agm1984and @Jaromanda Xtold me but it still doesn't work :(
我做了@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))
But then again... it doesn't work unless I call initinside download.
不过话又说回来......除非我把它不起作用init里面download。
回答by Omar
The problem here is that initis asynchronous. Using it like this:
这里的问题是它init是异步的。像这样使用它:
const downloader = new ImageDownloader;
downloader.download();
The downloadfunction is being executed while initstill did not finish yet.
该download函数正在执行中,init但尚未完成。
I wouldn't call the init method in the constructor. What I would do is something like this:
1- remove the init call from the constructor.
2- use the class like this:
我不会在构造函数中调用 init 方法。我会做的是这样的:
1- 从构造函数中删除 init 调用。
2-使用这样的类:
const downloader = new ImageDownloader();
downloader.init()
.then(() => downloader.download());
and if you are calling init in an asyncfunction you can do:
如果你在一个async函数中调用 init你可以这样做:
await downloader.init();
const result = await downloader.download();

