如何确保在 NodeJS 中一个异步函数在另一个异步函数开始之前完成?
How to make sure one async function is completed before another starts in NodeJS?
我是新手,可能遗漏了一些微不足道的东西。
public async RunWorkFlow() {
const zipFile = await DownloadZipFile(123, `abc`);
await UnzipZippedArtifacts(zipFile);
}
当我尝试上述操作时,有时解压缩方法会在下载完成之前启动,并导致尝试解压缩损坏的(下载一半的)文件。 DownloadZipFile
和 UnzipZippedArtifacts
都是异步方法,我想确保 DownloadZipFile
在 UnzipZippedArtifacts
开始之前完成。
解压缩时出现错误
Error: Corrupted zip: can't find end of central directory
说明文件下载不正确
private async DownloadZipFile(buildId: number, projectName: string) : Promise<string>
{
const buildApi = await this.api.getBuildApi();
const artifactDetails = await buildApi.getArtifacts(buildId, projectName);
const localZipFileName = buildId.toString() + `_` + artifactDetails[0]?.name + `_` + Date.now() + ".zip";
const artifactStream = await buildApi.getArtifactContentZip(
buildId,
artifactDetails[0]?.name,
projectName);
const localZipFileStream = fs.createWriteStream(localZipFileName);
await artifactStream
.pipe(localZipFileStream)
.on(`finish`, () => {
localZipFileStream.close();
this.logger.I(`Artifact zip file was download successfully for buildId ${buildId} in the project ${projectName}, filename is ${localZipFileName}`);
});
return localZipFileName;
}
artifactStream.pipe(localZipFileStream).on(...)
不是 return Promise,所以 await
没有意义。它仅注册一个回调(on
中的第二个参数),以便在“完成”事件发生时调用。
为了 return 来自 DownloadZipFile
的 Promise,您需要将 artifactStream.pipe(localZipFileStream).on(...)
包装在 Promise 中,然后在调用回调函数时解析该 Promise:
private async DownloadZipFile(buildId: number, projectName: string) : Promise < string >
{
const buildApi = await this.api.getBuildApi();
const artifactDetails = await buildApi.getArtifacts(buildId, projectName);
const localZipFileName = buildId.toString() + `_` + artifactDetails[0]?.name + `_` + Date.now() + ".zip";
const artifactStream = await buildApi.getArtifactContentZip(
buildId,
artifactDetails[0]?.name,
projectName);
const localZipFileStream = fs.createWriteStream(localZipFileName);
return new Promise(function (resolve, reject) {
// resolve with location of saved file
artifactStream
.pipe(localZipFileStream)
.on('finish', () => {
localZipFileStream.close();
this.logger.I(`Artifact zip file was download successfully for buildId ${buildId} in the project ${projectName}, filename is ${localZipFileName} `);
resolve(localZipFileStream);
});
})
}
我是新手,可能遗漏了一些微不足道的东西。
public async RunWorkFlow() {
const zipFile = await DownloadZipFile(123, `abc`);
await UnzipZippedArtifacts(zipFile);
}
当我尝试上述操作时,有时解压缩方法会在下载完成之前启动,并导致尝试解压缩损坏的(下载一半的)文件。 DownloadZipFile
和 UnzipZippedArtifacts
都是异步方法,我想确保 DownloadZipFile
在 UnzipZippedArtifacts
开始之前完成。
解压缩时出现错误
Error: Corrupted zip: can't find end of central directory
说明文件下载不正确
private async DownloadZipFile(buildId: number, projectName: string) : Promise<string>
{
const buildApi = await this.api.getBuildApi();
const artifactDetails = await buildApi.getArtifacts(buildId, projectName);
const localZipFileName = buildId.toString() + `_` + artifactDetails[0]?.name + `_` + Date.now() + ".zip";
const artifactStream = await buildApi.getArtifactContentZip(
buildId,
artifactDetails[0]?.name,
projectName);
const localZipFileStream = fs.createWriteStream(localZipFileName);
await artifactStream
.pipe(localZipFileStream)
.on(`finish`, () => {
localZipFileStream.close();
this.logger.I(`Artifact zip file was download successfully for buildId ${buildId} in the project ${projectName}, filename is ${localZipFileName}`);
});
return localZipFileName;
}
artifactStream.pipe(localZipFileStream).on(...)
不是 return Promise,所以 await
没有意义。它仅注册一个回调(on
中的第二个参数),以便在“完成”事件发生时调用。
为了 return 来自 DownloadZipFile
的 Promise,您需要将 artifactStream.pipe(localZipFileStream).on(...)
包装在 Promise 中,然后在调用回调函数时解析该 Promise:
private async DownloadZipFile(buildId: number, projectName: string) : Promise < string >
{
const buildApi = await this.api.getBuildApi();
const artifactDetails = await buildApi.getArtifacts(buildId, projectName);
const localZipFileName = buildId.toString() + `_` + artifactDetails[0]?.name + `_` + Date.now() + ".zip";
const artifactStream = await buildApi.getArtifactContentZip(
buildId,
artifactDetails[0]?.name,
projectName);
const localZipFileStream = fs.createWriteStream(localZipFileName);
return new Promise(function (resolve, reject) {
// resolve with location of saved file
artifactStream
.pipe(localZipFileStream)
.on('finish', () => {
localZipFileStream.close();
this.logger.I(`Artifact zip file was download successfully for buildId ${buildId} in the project ${projectName}, filename is ${localZipFileName} `);
resolve(localZipFileStream);
});
})
}