将嵌套的 'for' 循环转换为 Promise,对于 Promise?嵌套承诺?
Convert nested 'for' loops into a Promise, for a Promise? Nested Promises?
我有一个数组,其中的值是由“/”分隔的序列,以及一个“mapSeries”Promise(用于使用映射进行串行迭代的辅助函数)循环遍历每个序列中的每个值。
现在,该语句以一个嵌套的 'for' 循环开始,该循环将一个序列拆分为字符串,然后将这些值推送到一个空数组以传递给 'mapSeries' promise..
经过测试发现只有原数组只有一个序列才有效,因为多个序列运行并行
如何将这写成一个承诺,即 运行 对每个序列连续,然后对给定序列中的每个元素连续?
这是 for 循环的尝试(适用于单个序列):
var sequences = ['one/two/three', 'alpha/beta'];
var elements = [];
for (i=0; i<sequences.length; i++) {
var series = sequences[i].split("/");
for (j=0; j<series.length; j++) {
elements.push(series[j]);
}
var items = mapSeries(elements, function(element) {
// do stuff with 'one', then 'two', then 'three'
// when done..next series
// do stuff with 'alpha', then 'beta'
})
elements = []; // reset elements array for next series
} // for sequences.length
这是对 Promise 的尝试(在 element.charAt.. 处出错):
var sequences = ['one/two/three', 'alpha/beta'];
var elements = [];
var items = mapSeries(sequences, function(sequence) {
sequence = sequence.split("/");
return mapSeries(sequence, function(series) {
elements.push(series);
return elements;
}).then(function(elements) {
return mapSeries(elements, function(element){
var element = element.charAt(0).toLowerCase() + element.slice(1); // first letter lowercase
// do stuff with 'one', then 'two', then 'three'
// when done..next series
// do stuff with 'alpha', then 'beta'
});
});
elements = []; // reset elements array for next series
});
mapSeries 辅助函数:
function mapSeries(things, fn) {
var results = [];
return Promise.each(things, function(value, index, length) {
var ret = fn(value, index, length);
results.push(ret);
return ret;
}).thenReturn(results).all();
}
一些快速、丑陋、未经测试的示例,但我希望你能理解:
var sequences = ['one/two/three', 'alpha/beta'];
var elements = [];
var promise = null;
for (var i = 0; i < sequences.length; i++) {
(function(series){
function doStuff() {
for (var j = 0; j < series.length; j++) {
elements.push(series[j]);
}
return mapSeries(elements, function(element) {
// async stuff
})
}
if (promise) {
promise = promise.then(doStuff)
} else {
promise = doStuff()
}
})( sequences[i].split("/") )
}
promise.then(function(){
// ...
})
这部分代码似乎没什么用,因为 elements
与 sequence
相同,并且推送不是异步的,因此您也可以使用 for
循环:
sequence = sequence.split("/");
return mapSeries(sequence, function(series) {
elements.push(series);
return elements;
})
你也可能有一个错误,因为
elements = []; // reset elements array for next series
永远不会执行 - 它在 return
语句之后;并且无论如何都不会等待异步结果。
你的代码应该简单地省略那些 elements
数组,并且只是
var sequences = ['one/two/three', 'alpha/beta'];
var items = mapSeries(sequences, function(sequence) {
return mapSeries(sequence.split("/"), function(elements) {
return mapSeries(elements, function(element) {
// do async stuff with the element, and return a promise
});
});
});
顺便说一句,我建议使用 Bluebird 的 "native" map
method with the concurrency
option 设置为 1
.
而不是自定义 mapSeries
实现
我有一个数组,其中的值是由“/”分隔的序列,以及一个“mapSeries”Promise(用于使用映射进行串行迭代的辅助函数)循环遍历每个序列中的每个值。
现在,该语句以一个嵌套的 'for' 循环开始,该循环将一个序列拆分为字符串,然后将这些值推送到一个空数组以传递给 'mapSeries' promise..
经过测试发现只有原数组只有一个序列才有效,因为多个序列运行并行
如何将这写成一个承诺,即 运行 对每个序列连续,然后对给定序列中的每个元素连续?
这是 for 循环的尝试(适用于单个序列):
var sequences = ['one/two/three', 'alpha/beta'];
var elements = [];
for (i=0; i<sequences.length; i++) {
var series = sequences[i].split("/");
for (j=0; j<series.length; j++) {
elements.push(series[j]);
}
var items = mapSeries(elements, function(element) {
// do stuff with 'one', then 'two', then 'three'
// when done..next series
// do stuff with 'alpha', then 'beta'
})
elements = []; // reset elements array for next series
} // for sequences.length
这是对 Promise 的尝试(在 element.charAt.. 处出错):
var sequences = ['one/two/three', 'alpha/beta'];
var elements = [];
var items = mapSeries(sequences, function(sequence) {
sequence = sequence.split("/");
return mapSeries(sequence, function(series) {
elements.push(series);
return elements;
}).then(function(elements) {
return mapSeries(elements, function(element){
var element = element.charAt(0).toLowerCase() + element.slice(1); // first letter lowercase
// do stuff with 'one', then 'two', then 'three'
// when done..next series
// do stuff with 'alpha', then 'beta'
});
});
elements = []; // reset elements array for next series
});
mapSeries 辅助函数:
function mapSeries(things, fn) {
var results = [];
return Promise.each(things, function(value, index, length) {
var ret = fn(value, index, length);
results.push(ret);
return ret;
}).thenReturn(results).all();
}
一些快速、丑陋、未经测试的示例,但我希望你能理解:
var sequences = ['one/two/three', 'alpha/beta'];
var elements = [];
var promise = null;
for (var i = 0; i < sequences.length; i++) {
(function(series){
function doStuff() {
for (var j = 0; j < series.length; j++) {
elements.push(series[j]);
}
return mapSeries(elements, function(element) {
// async stuff
})
}
if (promise) {
promise = promise.then(doStuff)
} else {
promise = doStuff()
}
})( sequences[i].split("/") )
}
promise.then(function(){
// ...
})
这部分代码似乎没什么用,因为 elements
与 sequence
相同,并且推送不是异步的,因此您也可以使用 for
循环:
sequence = sequence.split("/"); return mapSeries(sequence, function(series) { elements.push(series); return elements; })
你也可能有一个错误,因为
elements = []; // reset elements array for next series
永远不会执行 - 它在 return
语句之后;并且无论如何都不会等待异步结果。
你的代码应该简单地省略那些 elements
数组,并且只是
var sequences = ['one/two/three', 'alpha/beta'];
var items = mapSeries(sequences, function(sequence) {
return mapSeries(sequence.split("/"), function(elements) {
return mapSeries(elements, function(element) {
// do async stuff with the element, and return a promise
});
});
});
顺便说一句,我建议使用 Bluebird 的 "native" map
method with the concurrency
option 设置为 1
.
mapSeries
实现