一个简单的 async/await 函数的具体例子会被表达为 Promises 吗?
What would a specific example of a simple async/await function be expressed as Promises?
我想了解 TypeScript 中 async
/await
和 Promise
之间的关系,但我觉得自己太困惑了。
特别是,我试图了解示例函数 downloadFileAA
的 async
/await
版本如何映射到使用 [=14] 的实现=]s 代替。 Promise
s 在幕后发生了什么?显然,我的 Promise
版本都不令人满意,也没有完全捕捉到 async
/await
版本中发生的事情(downloadFilePromise
从不报告成功或失败,并且 downloadFilePromise2
需要一些奇怪的冗余:resolve
的参数中的 result.then()
以通过类型检查),但我不确定为什么。
基于 Promise
的 downloadFileAA
版本会是什么样子?有理由比 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 - .then
和 await
都需要一个 Promise(至少要明智地使用)。
您的 downloadFilePromise
函数已损坏,因为它构造了一个根据定义永远不会解析的 Promise - 您必须调用 resolve
或 reject
参数才能使构造的 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
当有多个值需要等待(串行)时表现最好,但在其他情况下都可以正常工作(当然,只要它们得到正确实施)。
我想了解 TypeScript 中 async
/await
和 Promise
之间的关系,但我觉得自己太困惑了。
特别是,我试图了解示例函数 downloadFileAA
的 async
/await
版本如何映射到使用 [=14] 的实现=]s 代替。 Promise
s 在幕后发生了什么?显然,我的 Promise
版本都不令人满意,也没有完全捕捉到 async
/await
版本中发生的事情(downloadFilePromise
从不报告成功或失败,并且 downloadFilePromise2
需要一些奇怪的冗余:resolve
的参数中的 result.then()
以通过类型检查),但我不确定为什么。
基于 Promise
的 downloadFileAA
版本会是什么样子?有理由比 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 - .then
和 await
都需要一个 Promise(至少要明智地使用)。
您的 downloadFilePromise
函数已损坏,因为它构造了一个根据定义永远不会解析的 Promise - 您必须调用 resolve
或 reject
参数才能使构造的 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
当有多个值需要等待(串行)时表现最好,但在其他情况下都可以正常工作(当然,只要它们得到正确实施)。