我正在开发一个项目,使用API收集数据,然后绘制html来表示数据;有3种异步方法用于收集数据,当然还有相关的同步方法来为每种方法绘制html。
我希望在这里得到回复以帮助我确保我正在有效地完成这项工作 - 我将展示的代码工作,因此我的项目不会受到与此代码相关的任何问题的影响,但我不确定它的功效。
对于3个异步方法 - 让我们将它们称为async1,async2,async3(或者尊重地截断为a1,a2,a3) - 假设如下:
每个异步返回一个对象数组;然后对a2和a3迭代a1的结果,并将每个异步的所有结果推送到它们自己的'master'数组;然后迭代生成的数组以使同步方法将html内容绘制到页面,这样每个a1对象都有自己的容器,其中是来自a2的相关对象的容器,其中是来自a3的相关对象的容器。 / p>
这是我所拥有的伪代码表示(假设所有这些都包含在一个函数中):
//establish master arrays for each async method result
var a1array = [], a2array = [], a3array = [];
//establish Deferreds for each async master array, html
var a1arrDfd = $.Deferred(), a1htmlDfd = $.Deferred();
var a2arrDfd = $.Deferred(), a2htmlDfd = $.Deferred();
var a3arrDfd = $.Deferred(), a3htmlDfd = $.Deferred();
//get a1 data
async1(params).done(fn(a1data) {
//iterate over a1 return and push to a1 master array
var i, ilen = a1data.length, idone = 0;
for (i = 0; i < ilen; i++) {
a1array.push(a1data[i]);
idone++;
//if at last iteration of a1data array,
//a1's master array is complete
if (idone === ilen) { a1arrDfd.resolve(); }
}
}).done(fn(a1data) {
var j, jlen = a1data.length, jdone = 0;
//loop thru a1data array to get a2 data and
//push a2data to a2 master array
for (j = 0; j < jlen; j++) {
async2(param + a1data[j].key + param).done(fn(a2data) {
var k, klen = a2data.length, kdone = 0;
jdone++;
//loop thru a2data array to push to a2 master array
for (k = 0; k < klen; k++) {
a2array.push(a2data[k]);
kdone++;
//if at last a1data iteration and a2data iterant,
//a2's master array is complete
if (jdone === jlen && kdone === klen) { a2arrDfd.resolve(); }
}
});
}
}).done(fn(a1data) {
var l, llen = a1data.length, ldone = 0;
//loop thru a1data array to get a3 data and
//push a3data to a3 master array
for (l = 0; l < llen; l++) {
async3(param + a1data[l].key + param).done(fn(a3data) {
var m, mlen = a3data.length, mdone = 0;
ldone++;
//loop thru a3data array to push to a3 master array
for (m = 0; m < mlen; m++) {
a3array.push(a3data[m]);
mdone++;
//if at last a1data iteration and a3data iterant
//a3's master array is complete
if (ldone === llen && mdone === mlen) { a3arrDfd.resolve(); }
}
});
}
});
//listen for completion of async1array, then
//paint html containers for each object in async1 array
$.when(a1arrDfd).done(fn() {
var n, nlen = a1array.length, ndone = 0;
for (n = 0; n < nlen; n++) {
a1paintHtml;
ndone++;
//if at last a1array iteration,
//a1's html painting is complete
if (ndone === nlen) { a1htmlDfd.resolve(); }
}
});
//listen for completion of async1 html containers and
//async2 array, then paint containers for
//each object in async2 array
$.when(a1htmlDfd, a2arrDfd).done(fn() {
var o, olen = a2array.length, odone = 0;
for (o = 0; o < olen; o++) {
a2paintHtml;
odone++;
//if at last a2array iteration,
//a2's html painting is complete
if (odone === olen) { a2htmlDfd.resolve(); }
}
});
//listen for completion of async2 html containers and
//async3 array, then paint containers for
//each object in async3 array
$.when(a2htmlDfd, a3arrDfd).done(fn() {
var p, plen = a3array.length, pdone = 0;
for (p = 0; p < plen; p++) {
a3paintHtml;
pdone++;
//if at last a3array iteration,
//a3's html painting is complete
if (pdone === plen) { a3htmlDfd.resolve(); }
}
});
注意:如果您倾向于使用setTimeout回复,请提供一个解释为什么 - IMO,使用setTimeout方法似乎是任意的,特别是在考虑如何确定使用什么作为延迟参数时,所以你有教育我在这方面的假设是不正确的。
提前感谢任何建议
答案 0 :(得分:2)
经过近2个月的离去之后,我重新审视了这个项目,掌握了关于JS中Promises的更多知识,现在有以下内容摆脱了延迟反模式:
const a1array = [], a2array = [], a3array = [];
const a1get = async1(params).then(data => {
a1array.push(...data);
return a1array;
})
const a2get = a1get.then(a1data =>
Promise.all(a1data.map(a1 =>
async2(param + a1.key + param)
.then(data => a2array.push(...data)))));
const a3get = a1get.then(a1data =>
Promise.all(a1data.map(a1 =>
async3(param + a1.key + param)
.then(data => a3array.push(...data)))));
Promise.all([a1get, a2get, a3get]).then(() => {
a1paintHtml();
a2paintHtml();
a3paintHtml();
});