admin管理员组文章数量:1292121
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.
I created a local server that that will receive a post http method with user and password in it and a router called /download
that will only be accessed if the user is logged in, otherwise it will return 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 download
and query
so I though about creating an init
method 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.cookie
to use everywhere, but it doesn't work, it seems that init
is being called after every other method.
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 init
in the download
method.
If I put console.log(this.cookie)
in download
it returns an empty CookieJar
and if I put the same in init
it will return the right cookie but it appears AFTER the execution of download even tho I called it on the constructor before calling download
.
How to solve that? Thank you very much.
@edit
I made the changes that @agm1984 and @Jaromanda X told me but it still doesn't work :(
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 init
inside download
.
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.
I created a local server that that will receive a post http method with user and password in it and a router called /download
that will only be accessed if the user is logged in, otherwise it will return 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 download
and query
so I though about creating an init
method 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.cookie
to use everywhere, but it doesn't work, it seems that init
is being called after every other method.
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 init
in the download
method.
If I put console.log(this.cookie)
in download
it returns an empty CookieJar
and if I put the same in init
it will return the right cookie but it appears AFTER the execution of download even tho I called it on the constructor before calling download
.
How to solve that? Thank you very much.
@edit
I made the changes that @agm1984 and @Jaromanda X told me but it still doesn't work :(
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 init
inside download
.
-
@JaromandaX I don't understand why I would return anything as the operations inside
init
anddownload
doesn't need to be shared anywhere and therequest-promise-native
will put the jar in thethis.cookie
for me (what I need), but the thing is the order things are running. Addingawait init()
indownload
is behaving like "I have to wait forinit
to finish and then continue" (something like that), but as I calledthis.init
in the constructor I though it wouldn't be needed. – vajehu Commented Oct 7, 2017 at 23:50 - Sorry, yeah, I misread your code – Jaromanda X Commented Oct 8, 2017 at 0:02
- as I said, I misread your code, ignore my changes :p - most of them are not required as I screwed up my knowledge of async/await :p – Jaromanda X Commented Oct 8, 2017 at 0:05
- That is okay, you tried to help and I fully understand what you mean. Thank you anyway. – vajehu Commented Oct 8, 2017 at 0:06
-
the problem now is that
download
wont wait forinit
– Jaromanda X Commented Oct 8, 2017 at 0:07
1 Answer
Reset to default 2The problem here is that init
is asynchronous. Using it like this:
const downloader = new ImageDownloader;
downloader.download();
The download
function is being executed while init
still did not finish yet.
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:
const downloader = new ImageDownloader();
downloader.init()
.then(() => downloader.download());
and if you are calling init in an async
function you can do:
await downloader.init();
const result = await downloader.download();
本文标签: javascriptES6 asyncawait in classesStack Overflow
版权声明:本文标题:javascript - ES6 asyncawait in classes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741544187a2384498.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论