一个简单的 async/await 函数的具体例子会被表达为 Promises 吗?

What would a specific example of a simple async/await function be expressed as Promises?

我想了解 TypeScript 中 async/awaitPromise 之间的关系,但我觉得自己太困惑了。

特别是,我试图了解示例函数 downloadFileAAasync/await 版本如何映射到使用 [=14] 的实现=]s 代替。 Promises 在幕后发生了什么?显然,我的 Promise 版本都不令人满意,也没有完全捕捉到 async/await 版本中发生的事情(downloadFilePromise 从不报告成功或失败,并且 downloadFilePromise2需要一些奇怪的冗余:resolve 的参数中的 result.then() 以通过类型检查),但我不确定为什么。

基于 PromisedownloadFileAA 版本会是什么样子?有理由比 async/await 版本更喜欢它(或不喜欢它)吗?

import * as FileSystem from 'expo-file-system'

const callback = ( downloadProgress ) => {
    const progress = downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite
    console.log(
        `${Number( progress )
            .toLocaleString( undefined, { style: 'percent', minimumFractionDigits: 0 } )
            .padStart( 5, ' ' )} of ${downloadProgress.totalBytesExpectedToWrite} bytes`
    )
}

const downloadResumable = FileSystem.createDownloadResumable(
    'http://...',
    FileSystem.documentDirectory + 'somebigfile',
    {},
    callback
)

const downloadFileAA = async () => {
    try {
        console.log( 'Starting download (with async/await)... ' )
        const result = await downloadResumable.downloadAsync()
        console.log( result ? `Finished downloading to ${result.uri}` : 'Undefined result?'  )
    } catch ( e ) {
        console.error( `Failed download: ${e.message}` )
    }
}

const downloadFilePromise = () => {
        console.log( 'Starting download (with Promise)... ' )
        new Promise<FileSystem.FileSystemDownloadResult>(  ( resolve, reject ) =>
            downloadResumable.downloadAsync()
         )
            .then( ( result ) => console.log( `Finished downloading to ${result.uri}` ) )
            .catch( ( reason ) => console.error( `Failed download: ${reason}` ) )
}

const downloadFilePromise2 = () => {
        console.log( 'Starting download (with Promise Two)... ' )
        new Promise<FileSystem.FileSystemDownloadResult>(  ( resolve, reject ) => {
            const result = downloadResumable.downloadAsync()
            result  ? resolve( result.then() ) : reject( result )
        } )
            .then( ( result ) => console.log( `Finished downloading to ${result.uri}` ) )
            .catch( ( reason ) => console.error( `Failed download: ${reason}` ) )
}

假设 downloadAsync returns 一个 Promise 并且 console.log 没有抛出,这个

const downloadFileAA = async () => {
    try {
        console.log( 'Starting download (with async/await)... ' )
        const result = await downloadResumable.downloadAsync()
        console.log( result ? `Finished downloading to ${result.uri}` : 'Undefined result?'  )
    } catch ( e ) {
        console.error( `Failed download: ${e.message}` )
    }
}

相当于

const downloadFileAA = () => {
    console.log('Starting download (with async/await)... ')
    return downloadResumable.downloadAsync()
        .then((result) => {
            console.log(result ? `Finished downloading to ${result.uri}` : 'Undefined result?')
        })
        .catch((e) => {
            console.error(`Failed download: ${e.message}`);
        });
};

await 的作用是取代 .then。它不会取代 Promises - .thenawait 都需要一个 Promise(至少要明智地使用)。

您的 downloadFilePromise 函数已损坏,因为它构造了一个根据定义永远不会解析的 Promise - 您必须调用 resolvereject 参数才能使构造的 Promise解决。但是因为它看起来像 downloadAsync already returns 一个 Promise,构建另一个 Promise 来包围它 doesn't make any sense - 只需使用你拥有的 Promise 而不是制作一个新的。

Is there a reason to prefer it (or not) over the async/await version?

这纯粹是一种风格选择。 IMO await 当有多个值需要等待(串行)时表现最好,但在其他情况下都可以正常工作(当然,只要它们得到正确实施)。