簡體   English   中英

如何將 async/await 與 Promise 子類一起使用?

[英]How can I use async/await with a Promise subclass?

我有一個自定義Promise class。如何將它與async/await一起使用?

type Resolve<T> = (x: T | PromiseLike<T>) => void
type Reject     = (reason?: any) => void

class LoggingPromise<T> extends Promise<T> {
    constructor(f: (res: Resolve<T>, rej: Reject) => void) {
        super((resolve, reject) => f(
            (x) => {console.log(`I resolved to ${x}!`); resolve(x)}, 
            reject
        ))
    }
}

function inc(x: number): LoggingPromise<number> {
    return new LoggingPromise(resolve => resolve(x + 1))
}

我可以await我的自定義 promise 就好了:

function logAnswer() {
    const answer = await inc(2)
    console.log(`I got answer ${answer}`)
}

>> logAnswer()
// I resolved to 3!
// I got answer 3!

但是我無法從async方法返回我的自定義 promise:

async torgle(): LoggingPromise<number> {
    const answer = await inc(2)
    return LoggingPromise.resolve(answer * 5)
}
// ERROR: The return type of an async function or method must be the global Promise<T> type. 
// Did you mean to write 'Promise<number>'?

如果我ts-ignore這個,它工作正常*:

// @ts-ignore <-- can I do something about this?
async function torgle(x: number): LoggingPromise<number> {
    const answer = await inc(x)
    return LoggingPromise.resolve(answer * 5)
}

async function main() {
    const answer = await torgle(2)
    console.log(`I got answer ${answer}!`)
}

>> main()
// I resolved to 3!
// I resolved to 15!
// I got answer 15!

請參閱Typescript 游樂場示例

(*好吧,有點。我不明白為什么它會產生undefined的承諾,但它們似乎不會影響最終結果。)

有什么方法可以說服 Typescript 讓我在返回自定義 promise 的方法上使用async關鍵字嗎?

如何將 async/await 與 Promise 子類一起使用?

你不能。 您可以await任何 thenable(具有 .then .then()方法的對象),包括 promise 子類的實例。 但是async function將始終返回本機Promise ,永遠不會返回子類實例。

有什么方法可以說服 Typescript 讓我在返回自定義 promise 的方法上使用 async 關鍵字嗎?

不,您擁有的不是返回自定義 promise 的方法。這不是 TypeScript 可以“說服”允許的。 這是 JavaScript 運行時施加的基本限制。

[如果我忽略錯誤],它工作正常

不,它沒有。 還是一樣的

async torgle(): Promise<number> {
//              ^^^^^^^^^^^^^^^
    const answer = await inc(2)
    return LoggingPromise.resolve(answer * 5)
}

記住async / await只是語法糖

torgle(): Promise<number> {
    return new Promise((resolve, reject) => {
        Promise.resolve(inc(2)).then(answer => {
            resolve(LoggingPromise.resolve(answer * 5));
        });
    });
}

調用LoggingPromise.resolve()將記錄結果並沒有什么區別——返回值仍然是原生的 promise:

const promise = torgle();
console.log(promise instanceof LoggingPromise); // false

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM