qui*_*inz 2 javascript node.js promise
我在我的业余爱好节点项目中遇到这个问题.我有一个函数(processDataSet)正在处理数据数组(inputArray)并返回一个promise.该函数使用for循环遍历输入数组并saveObjectData在每一轮调用函数.此保存功能处理单个数据条目并返回承诺.
似乎如果saveObjectData函数失败,processDataSet函数捕获返回拒绝,但它自己reject似乎没有在for循环中正确调用.我认为这是一个时间问题,我不明白.查看代码下方的输出打印结果.
function processDataSet(inputArray, scriptConfig) {
var contentType = scriptConfig.contentType;
return new Promise(function(resolve, reject) {
if(!Array.isArray(inputArray)) {
return reject(new Error("Input data is not an array. Cannot process."));
}
if(!scriptConfig) {
return reject(new Error("Invalid scriptConfig"));
}
if(!typeof contentType === "string" && !contentType instanceof String) {
return reject(new Error("Invalid contentType for the data set. The parameter should be a string."));
}
console.log("Post processing data for the script " + scriptConfig.name + " (type: " + scriptConfig.contentType + ")");
// Iterate through the input array and handle the objects one-by-one
for (var i = 0; i < inputArray.length; i++) {
saveObjectData(inputArray[i], scriptConfig)
.then(() => {
//continue;
})
.catch(err => {
console.log("TEST PRINT " + scriptConfig.name);
return reject(new Error("Processing data object failed.", err));
});
}
console.log("Resolve " + scriptConfig.name);
return resolve();
});
}
Run Code Online (Sandbox Code Playgroud)
输出打印在控制台中:
Post processing data for the script Script1 (type: Season)
Resolve Script1
TEST PRINT Script1
Run Code Online (Sandbox Code Playgroud)
似乎包含"Resolve ..."的最后一个日志行在错误处理程序中的"TEST PRINT ..."之前打印.为什么这样做,如何在返回之前让执行等待所有数据条目的完全解析processDataSet?
我不完全确定在我的情况下是否多余processDataSet才能返回承诺,但我将其作为我的故障排除的一部分.
您的for循环不会逐个保存对象.它开始保存第一个,然后是第二个,依此类推,然后循环结束,你立即解决你的承诺.只有在那之后,在循环中创建的承诺才能解决,其中一些可能会试图拒绝已经履行的承诺.
避免Promise构造函数反模式,而是正确地链接你的承诺.
如果你可以立即触发所有保存以便它们同时运行,你可以等待所有的保证Promise.all:
function processDataSet(inputArray, scriptConfig) {
if (!Array.isArray(inputArray)) {
return Promise.reject(new Error("Input data is not an array. Cannot process."));
}
if (!scriptConfig) {
return Promise.reject(new Error("Invalid scriptConfig"));
}
var contentType = scriptConfig.contentType;
if (typeof contentType !== "string") {
return Promise.reject(new Error("Invalid contentType for the data set. The parameter should be a string."));
}
console.log("Post processing data for the script " + scriptConfig.name + " (type: " + scriptConfig.contentType + ")");
return Promise.all(inputArray.map(input => {
return saveObjectData(input, scriptConfig)
.catch(err => {
console.log("TEST PRINT " + scriptConfig.name);
throw new Error("Processing data object failed.", input, err);
});
})).then(results => {
console.log("Resolve " + scriptConfig.name, results);
return;
});
}
Run Code Online (Sandbox Code Playgroud)
如果你坚持按顺序保存它们,我建议使用async/ await.
async function processDataSet(inputArray, scriptConfig) {
if (!Array.isArray(inputArray)) {
throw new Error("Input data is not an array. Cannot process.");
}
if (!scriptConfig) {
throw new Error("Invalid scriptConfig");
}
var contentType = scriptConfig.contentType;
if (typeof contentType !== "string") {
throw new Error("Invalid contentType for the data set. The parameter should be a string.");
}
console.log("Post processing data for the script " + scriptConfig.name + " (type: " + scriptConfig.contentType + ")");
for (var input of inputArray) {
try {
await saveObjectData(input, scriptConfig);
} catch (err) {
console.log("TEST PRINT " + scriptConfig.name);
throw new Error("Processing data object failed.", input, err);
}
}
console.log("Resolve " + scriptConfig.name);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
84 次 |
| 最近记录: |