注意:我不能使用async
。
在需要遍历数组并对其成员执行相同功能并返回Promise的情况下,我喜欢使用reduce
模式,例如:
function get_count() {
return new Promise(function(resolve, reject) {
resolve(3);
});
}
function recursively_execute(data) {
return new Promise(function(resolve, reject) {
resolve(data);
});
}
function reduce_promise_pattern() {
const get_batch_run_count = get_count();
const batch_process = get_batch_run_count.then((count_value) => {
const run_count = new Array(count_value).fill('batch');
function recursive_function(data) {
console.log('Running batch!');
return recursively_execute(data).then(() => {
return data;
});
}
return run_count.reduce((previous_promise) => {
return previous_promise.then((previous_response) => {
test_data = {
'test': 1
};
return recursive_function(test_data);
})
}, Promise.resolve())
});
return batch_process;
}
这将运行3次,因为run_count
基本上会构建3个元素的数组。尽管可以,但是对我来说这就像是一个hack。
当我的列表已经预先定义了唯一项并且这些项单独使用时,这种方法就可以使用了,例如,如果我有3个步骤,则可以在内部单独使用,将其减少为基于的数据要经历的这三个步骤都是唯一的,并且每一步的数据将在一次运行中使用...但是就我而言?我只是在欺骗系统,使他们认为这些是不同的项目。
有什么替代方法?
答案 0 :(得分:3)
您已达到Promise链的极限,尽管它们无法读取,但它们的工作原理。这就是为什么引入async
/ await
来处理这些用例的原因,有了它们,您可以停止各种(嵌套的)循环,而不必为每个用例维护承诺。
async function reducePromisePattern() {
for(let i = await getCount(); i >= 0; i--) {
await recursiveFunction({'test': 1 });
}
}
如果您不能使用/转换async
,您仍然可以编写一些小助手来为您执行循环,例如:
function loopAsync(times, fn) {
function task() {
times--;
if(times <= 0) return;
return fn().then(task);
}
return Promise.resolve().then(task);
}
function reducePromisePattern() {
return getCount().then(function(count) {
return asyncLoop(count, function() {
return recursiveFunction({ test: 1 });
});
});
}
答案 1 :(得分:0)
这里有两个选项,彼此之间没有嵌套功能。第一个函数仅使用for循环,而第二个函数使用递归解决方案。两种解决方案的最后一个参数都是可选的,并且仅在要将返回数据从一次运行传递到下一次运行时才使用(类似于reduce
)。
const sleep = () => new Promise(resolve => setTimeout(resolve, Math.random() * 1500 + 500));
// solution #1 - for-loop
function times1(n, callback, init) {
var promise = Promise.resolve(init);
for (; n > 0; --n) {
promise = promise.then(val => callback(val));
}
return promise;
}
// example usage
times1(3, n => {
console.log("solution #1 -", n);
return sleep().then(() => n + 1);
}, 0);
// solution #2 - recursive
function times2(n, callback, init) {
var promise = Promise.resolve(init);
if (n <= 0) return promise;
return promise.then(val => times2(n - 1, callback, callback(val)));
}
// example usage
times2(3, n => {
console.log("solution #2 -", n);
return sleep().then(() => n + 1);
}, 0);