Node.js:顺序执行异步任务
Node.js: Sequential execution of asynchronous tasks
我有一组对象类似于:
let builds = [
{ status: "Failed"},
{ status: "Completed"},
{ status: "Building"},
{ status: "Building"},
{ status: "Failed"},
{ status: "Cancelled"},
...
]
元素的数量会有所不同,每个元素的 status
也会有所不同,最小数组大小为零。
我需要编写一个函数:
- 遍历数组并查找
status
为 Building
的任何项目
- 将这些项目的
status
更新为 Cancelled
- 当
Building
不再出现时,在数组中推送一个类似于:{ status: "Building" }
的新项目
问题是数组存储在 MongoDB 中,因此每个操作都需要以异步方式持久保存到数据库中。我对所有事情都使用 Q promises。
我目前的尝试看起来像这样:
let count=0; // Keep track of how many "builds" in "Building" state
module.getAllBuilds((builds) => {
builds.forEach((build) => {
if (build.status == "Building") {
count++;
module.cancelBuild(build)
.then(() => {
if (!--count) { // When counter is zero, all builds have been dealt with.
module.newBuild();
return;
}
})
}
})
module.newBuild(); // Get here if the build array is empty or no builds in "Building" state
})
我正在使用 count
变量来跟踪处于 Building
状态的条目数,很像堆栈。当堆栈为空时,我将继续创建新版本。
问题是我必须在两个地方之一调用 module.newBuild()
,具体取决于是否有构建处于 Building
状态。
有没有更好的实现方式?
首先过滤 "Building" 的构建数组 - 然后使用 Array#reduce
,您可以按如下方式简化代码
module.getAllBuilds((builds) => builds.filter(build => build.status == 'Building').reduce((promise, build) => promise.then(()=> module.cancelBuild(build)), Promise.resolve())
.then(() => module.newBuild()))
或者,试图让它更具可读性(但失败了):p
module.getAllBuilds((builds) =>
builds.filter(build => build.status == 'Building')
.reduce(
(promise, build) => promise.then(() => module.cancelBuild(build)),
Promise.resolve()
)
.then(() => module.newBuild()))
或者转译后的 ES5 版本
module.getAllBuilds(function (builds) {
return builds.filter(function (build) {
return build.status == 'Building';
}).reduce(function (promise, build) {
return promise.then(function () {
return module.cancelBuild(build);
});
}, Promise.resolve()).then(function () {
return module.newBuild();
});
});
注意:即使 builds
中没有 "Building",也会调用 module.newBuild()
我有一组对象类似于:
let builds = [
{ status: "Failed"},
{ status: "Completed"},
{ status: "Building"},
{ status: "Building"},
{ status: "Failed"},
{ status: "Cancelled"},
...
]
元素的数量会有所不同,每个元素的 status
也会有所不同,最小数组大小为零。
我需要编写一个函数:
- 遍历数组并查找
status
为Building
的任何项目 - 将这些项目的
status
更新为Cancelled
- 当
Building
不再出现时,在数组中推送一个类似于:{ status: "Building" }
的新项目
问题是数组存储在 MongoDB 中,因此每个操作都需要以异步方式持久保存到数据库中。我对所有事情都使用 Q promises。
我目前的尝试看起来像这样:
let count=0; // Keep track of how many "builds" in "Building" state
module.getAllBuilds((builds) => {
builds.forEach((build) => {
if (build.status == "Building") {
count++;
module.cancelBuild(build)
.then(() => {
if (!--count) { // When counter is zero, all builds have been dealt with.
module.newBuild();
return;
}
})
}
})
module.newBuild(); // Get here if the build array is empty or no builds in "Building" state
})
我正在使用 count
变量来跟踪处于 Building
状态的条目数,很像堆栈。当堆栈为空时,我将继续创建新版本。
问题是我必须在两个地方之一调用 module.newBuild()
,具体取决于是否有构建处于 Building
状态。
有没有更好的实现方式?
首先过滤 "Building" 的构建数组 - 然后使用 Array#reduce
,您可以按如下方式简化代码
module.getAllBuilds((builds) => builds.filter(build => build.status == 'Building').reduce((promise, build) => promise.then(()=> module.cancelBuild(build)), Promise.resolve())
.then(() => module.newBuild()))
或者,试图让它更具可读性(但失败了):p
module.getAllBuilds((builds) =>
builds.filter(build => build.status == 'Building')
.reduce(
(promise, build) => promise.then(() => module.cancelBuild(build)),
Promise.resolve()
)
.then(() => module.newBuild()))
或者转译后的 ES5 版本
module.getAllBuilds(function (builds) {
return builds.filter(function (build) {
return build.status == 'Building';
}).reduce(function (promise, build) {
return promise.then(function () {
return module.cancelBuild(build);
});
}, Promise.resolve()).then(function () {
return module.newBuild();
});
});
注意:即使 builds
module.newBuild()