具有 Typescript 和异步功能的 Aurelia:这是未定义的
Aurelia with Typescript and async functions: this is undefined
我在 aurelia 中使用打字稿,我想我找不到将变量放入正确范围的方法。
// detail.ts
import {autoinject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';
import {pApi} from './resources/services/APIService';
let http = new HttpClient();
let httpApi = new pApi(http);
@autoinject
export class PatDetail {
newDialog(patId, cat) {
let burl: string = 'bar/foo/list/';
const eurl: string = 'foo/bar/list/' + patId + '/';
let result: string[] = httpApi.getLists(eurl, burl);
}
}
这是 API 服务文件:
// APIService.ts
import {autoinject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
@autoinject
export class pApi {
constructor(private http: HttpClient) {
http.configure(config => {
config
.useStandardConfiguration()
.withBaseUrl('http://localhost:8000/')
});
}
getLists(eurl, burl) {
async function getQuote() {
await this.http.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
async function getBlock() {
await this.http.fetch(burl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
async function getBoth() {
return await Promise.all([getBlock])
}
getBoth().then(results => {
console.log(results)
return results
});
}
运行 这会引发错误:
Unhandled rejection TypeError: this is undefined
其实我想运行同时独立Promise,放到一个viewModel中。也许我也可以 运行 它作为普通的 Promise-call。
但我认为相当新的 async/await 调用适合此解决方案。
到目前为止,我找不到任何适合我的问题的解决方案/解释。由于我是 Typescript 和 Aurelia 的新手,所以我被困住了。
感谢您解释为什么会发生此错误或更好的方法。
这个:
async function getQuote() {
await this.http.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
应该是这个(去掉"function"关键字):
async getQuote() {
await this.http.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
通过使用 "function" 关键字,您将失去当前对象的上下文,并且 "this" 仅在函数内成为局部的。
编辑:稍微重写了我的回答
Donovan 的回答是正确的,由于作用域问题,您需要使用箭头函数而不是常规函数,但我会更进一步说您可能不应该那样内联它们。
Async 是为了摆脱 then
汤。如果您使用异步,最好充分利用它。您可以这样重写您的方法:
async getLists(eurl, burl) {
const results = await Promise.all([
this.getQuote(eurl),
this.getBlock(burl)
]);
console.log(results);
return results;
}
async getQuote(eurl) {
try {
const resp = await this.http.fetch(eurl);
const data = await resp.json();
console.log(data);
return data;
} catch (error) {
console.log(error);
}
}
async getBlock(burl) {
try {
const resp = await this.http.fetch(burl);
const data = await resp.json();
console.log(data);
return data;
} catch (error) {
console.log(error);
}
}
或者坚持你的方法,去 non-async 并简单地将未解决的承诺放在一个数组中,然后你可以 .all
在最后:
getLists(eurl, burl) {
const block = this.http
.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data);
return data;
})
.catch(error => console.log(error));
const quote = this.http
.fetch(burl)
.then(resp => resp.json())
.then(data => {
console.log(data);
return data;
})
.catch(error => console.log(error));
return Promise.all([block, quote])
.then(results => {
console.log(results);
return results;
});
}
但是混合它们=维护地狱:)
我在 aurelia 中使用打字稿,我想我找不到将变量放入正确范围的方法。
// detail.ts
import {autoinject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';
import {pApi} from './resources/services/APIService';
let http = new HttpClient();
let httpApi = new pApi(http);
@autoinject
export class PatDetail {
newDialog(patId, cat) {
let burl: string = 'bar/foo/list/';
const eurl: string = 'foo/bar/list/' + patId + '/';
let result: string[] = httpApi.getLists(eurl, burl);
}
}
这是 API 服务文件:
// APIService.ts
import {autoinject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
@autoinject
export class pApi {
constructor(private http: HttpClient) {
http.configure(config => {
config
.useStandardConfiguration()
.withBaseUrl('http://localhost:8000/')
});
}
getLists(eurl, burl) {
async function getQuote() {
await this.http.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
async function getBlock() {
await this.http.fetch(burl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
async function getBoth() {
return await Promise.all([getBlock])
}
getBoth().then(results => {
console.log(results)
return results
});
}
运行 这会引发错误:
Unhandled rejection TypeError: this is undefined
其实我想运行同时独立Promise,放到一个viewModel中。也许我也可以 运行 它作为普通的 Promise-call。 但我认为相当新的 async/await 调用适合此解决方案。
到目前为止,我找不到任何适合我的问题的解决方案/解释。由于我是 Typescript 和 Aurelia 的新手,所以我被困住了。 感谢您解释为什么会发生此错误或更好的方法。
这个:
async function getQuote() {
await this.http.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
应该是这个(去掉"function"关键字):
async getQuote() {
await this.http.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data)
return data
})
.catch(error => console.log(error))
}
通过使用 "function" 关键字,您将失去当前对象的上下文,并且 "this" 仅在函数内成为局部的。
编辑:稍微重写了我的回答
Donovan 的回答是正确的,由于作用域问题,您需要使用箭头函数而不是常规函数,但我会更进一步说您可能不应该那样内联它们。
Async 是为了摆脱 then
汤。如果您使用异步,最好充分利用它。您可以这样重写您的方法:
async getLists(eurl, burl) {
const results = await Promise.all([
this.getQuote(eurl),
this.getBlock(burl)
]);
console.log(results);
return results;
}
async getQuote(eurl) {
try {
const resp = await this.http.fetch(eurl);
const data = await resp.json();
console.log(data);
return data;
} catch (error) {
console.log(error);
}
}
async getBlock(burl) {
try {
const resp = await this.http.fetch(burl);
const data = await resp.json();
console.log(data);
return data;
} catch (error) {
console.log(error);
}
}
或者坚持你的方法,去 non-async 并简单地将未解决的承诺放在一个数组中,然后你可以 .all
在最后:
getLists(eurl, burl) {
const block = this.http
.fetch(eurl)
.then(resp => resp.json())
.then(data => {
console.log(data);
return data;
})
.catch(error => console.log(error));
const quote = this.http
.fetch(burl)
.then(resp => resp.json())
.then(data => {
console.log(data);
return data;
})
.catch(error => console.log(error));
return Promise.all([block, quote])
.then(results => {
console.log(results);
return results;
});
}
但是混合它们=维护地狱:)