如何在第一个异步函数完成后调用另一个异步函数?
how to call another async function after the first one completes?
我刚刚开始了解 Javascript 承诺的工作原理。我了解这些概念和一些代码。但是在下面的代码片段中,我没有看到“then()”或“catch()”,所以我不太确定如何修改它以便在它成功时调用另一个异步方法。
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
const spsync = require('gulp-spsync-creds').sync;
const sppkgDeploy = require('node-sppkg-deploy');
build.task("deploySharepointApps", {
execute: async () => {
const appList = require("./config/apps.json");
if (!pluginList) {
return;
}
for (const { name, sites } of appList.apps) {
const folderLocation = `./apps/${name}`;
for (const site of sites) {
await new Promise((resolve) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: creds.username,
password: creds.password,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
)
.on("finish", resolve);
});
}
}
},
});
由于此代码循环并复制/上传应用程序,因此我想使用此代码部署相同的应用程序:
return sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL
filename: filename,
skipFeatureDeployment: false,
verbose: true
});
你能为我指出正确的方向,告诉我如何“链接”这个吗?现在我正在尝试看看是否可以在 .on 之后添加 .then。
编辑 1
我试过像这样更改内部 for 循环:
for (const site of sites) {
// Here await each gulp pipeline to finish before moving on to the next.
await new Promise((resolve) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: uname,
password: pswd,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
)
.on("finish", resolve);
});
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: name,
skipFeatureDeployment: false,
verbose: true,
});
}//end for
它出现错误:
dev3:spfx-plugins admin$ gulp upload-sequential
Build target: DEBUG
[16:00:41] Using gulpfile /src/spfx-plugins/gulpfile.js
[16:00:41] Starting gulp
[16:00:41] Starting 'upload-sequential'...
[16:00:41] Uploading test.sppkg
[16:00:42] Upload successful 1679ms
[16:00:43] Published file 403ms
(node:69005) UnhandledPromiseRejectionWarning: Failed to call the API URL: https://<mydomain>.sharepoint.com/sites/<mysite>/AppCatalog/_api/site?$select=Id
(node:69005) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:69005) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
About to exit with code: 0
Process terminated before summary could be written, possible error in async code not continuing!
Trying to exit with exit code 1
所以我包装添加了一个 try/catch 但我永远不会陷入困境。
当前代码如下所示:
build.task("deploySharepointApps", {
execute: async () => {
try
{
const appList = require("./config/apps.json");
for (const { name, sites } of pluginList.plugins) {
for (const site of sites) {
[original code]
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: name,
skipFeatureDeployment: false,
verbose: true,
});
} // end for
} //end for
} catch (error) {
console.log('inside the error handler');
}
编辑 1:
我认为流 (pipe
) 部分存在一些错误,因此在该部分添加了错误处理,从您的日志中我看到至少有 1 个应用已成功发布,所以我相信 reject
部分将允许您检查更多错误。 UnhandledPromiseRejectionWarning
应该用 reject
部分修复。
for (const site of sites) {
// Here await each gulp pipeline to finish before moving on to the next.
await new Promise((resolve, reject) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: uname,
password: pswd,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
)
.on('error',
(error) => {
console.log('spsync error:', error);
reject(error);
})
.on("finish", resolve());
});
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: name,
skipFeatureDeployment: false,
verbose: true,
});
}//end for
我会使用 await
来做到这一点,因为您在标记为 async
的块内,而不是使用 then/catch
。当您调用 await
时,您只会在 await
代码解析时执行下一行代码,或者如果它拒绝它会转到 catch
块,如下所示:
const gulp = require("gulp");
const build = require("@microsoft/sp-build-web");
const spsync = require("gulp-spsync-creds").sync;
const sppkgDeploy = require("node-sppkg-deploy");
build.task("deploySharepointApps", {
execute: async () => {
const appList = require("./config/apps.json");
if (!pluginList) {
return;
}
try {
for (const { name, sites } of appList.apps) {
const folderLocation = `./apps/${name}`;
for (const site of sites) {
await new Promise((resolve) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: creds.username,
password: creds.password,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
) // Notice the resolve() here
.on("finish", resolve());
});
}
}
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: filename,
skipFeatureDeployment: false,
verbose: true,
});
} catch (error) {
console.log(err);
}
},
});
请注意,由于您使用的是 await new Promise(...)
,sppkgDeploy.deploy(...)
将是最后执行的操作。如果 await new Promise(...)
抛出错误,您将点击 catch
块而不是 运行 要部署的代码
我刚刚开始了解 Javascript 承诺的工作原理。我了解这些概念和一些代码。但是在下面的代码片段中,我没有看到“then()”或“catch()”,所以我不太确定如何修改它以便在它成功时调用另一个异步方法。
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
const spsync = require('gulp-spsync-creds').sync;
const sppkgDeploy = require('node-sppkg-deploy');
build.task("deploySharepointApps", {
execute: async () => {
const appList = require("./config/apps.json");
if (!pluginList) {
return;
}
for (const { name, sites } of appList.apps) {
const folderLocation = `./apps/${name}`;
for (const site of sites) {
await new Promise((resolve) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: creds.username,
password: creds.password,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
)
.on("finish", resolve);
});
}
}
},
});
由于此代码循环并复制/上传应用程序,因此我想使用此代码部署相同的应用程序:
return sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL
filename: filename,
skipFeatureDeployment: false,
verbose: true
});
你能为我指出正确的方向,告诉我如何“链接”这个吗?现在我正在尝试看看是否可以在 .on 之后添加 .then。
编辑 1
我试过像这样更改内部 for 循环:
for (const site of sites) {
// Here await each gulp pipeline to finish before moving on to the next.
await new Promise((resolve) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: uname,
password: pswd,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
)
.on("finish", resolve);
});
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: name,
skipFeatureDeployment: false,
verbose: true,
});
}//end for
它出现错误:
dev3:spfx-plugins admin$ gulp upload-sequential
Build target: DEBUG
[16:00:41] Using gulpfile /src/spfx-plugins/gulpfile.js
[16:00:41] Starting gulp
[16:00:41] Starting 'upload-sequential'...
[16:00:41] Uploading test.sppkg
[16:00:42] Upload successful 1679ms
[16:00:43] Published file 403ms
(node:69005) UnhandledPromiseRejectionWarning: Failed to call the API URL: https://<mydomain>.sharepoint.com/sites/<mysite>/AppCatalog/_api/site?$select=Id
(node:69005) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:69005) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
About to exit with code: 0
Process terminated before summary could be written, possible error in async code not continuing!
Trying to exit with exit code 1
所以我包装添加了一个 try/catch 但我永远不会陷入困境。 当前代码如下所示:
build.task("deploySharepointApps", {
execute: async () => {
try
{
const appList = require("./config/apps.json");
for (const { name, sites } of pluginList.plugins) {
for (const site of sites) {
[original code]
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: name,
skipFeatureDeployment: false,
verbose: true,
});
} // end for
} //end for
} catch (error) {
console.log('inside the error handler');
}
编辑 1:
我认为流 (pipe
) 部分存在一些错误,因此在该部分添加了错误处理,从您的日志中我看到至少有 1 个应用已成功发布,所以我相信 reject
部分将允许您检查更多错误。 UnhandledPromiseRejectionWarning
应该用 reject
部分修复。
for (const site of sites) {
// Here await each gulp pipeline to finish before moving on to the next.
await new Promise((resolve, reject) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: uname,
password: pswd,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
)
.on('error',
(error) => {
console.log('spsync error:', error);
reject(error);
})
.on("finish", resolve());
});
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: name,
skipFeatureDeployment: false,
verbose: true,
});
}//end for
我会使用 await
来做到这一点,因为您在标记为 async
的块内,而不是使用 then/catch
。当您调用 await
时,您只会在 await
代码解析时执行下一行代码,或者如果它拒绝它会转到 catch
块,如下所示:
const gulp = require("gulp");
const build = require("@microsoft/sp-build-web");
const spsync = require("gulp-spsync-creds").sync;
const sppkgDeploy = require("node-sppkg-deploy");
build.task("deploySharepointApps", {
execute: async () => {
const appList = require("./config/apps.json");
if (!pluginList) {
return;
}
try {
for (const { name, sites } of appList.apps) {
const folderLocation = `./apps/${name}`;
for (const site of sites) {
await new Promise((resolve) => {
gulp
.src(folderLocation)
.pipe(
spsync({
username: creds.username,
password: creds.password,
site: coreOptions.siteUrl + site,
libraryPath: coreOptions.appCatalog,
publish: true,
})
) // Notice the resolve() here
.on("finish", resolve());
});
}
}
await sppkgDeploy.deploy({
username: uname,
password: pswd,
absoluteUrl: catURL,
filename: filename,
skipFeatureDeployment: false,
verbose: true,
});
} catch (error) {
console.log(err);
}
},
});
请注意,由于您使用的是 await new Promise(...)
,sppkgDeploy.deploy(...)
将是最后执行的操作。如果 await new Promise(...)
抛出错误,您将点击 catch
块而不是 运行 要部署的代码