具有 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;
        });
}

但是混合它们=维护地狱:)