如何重构这个 promise 回退?
How to refactor this promise fallback?
这是一个经典的回退解决方案。如果第一个 el 没有被渲染,那么它会用其他渲染器重试。如何最好地重构它?
这段代码的问题在于:
- 渲染器需要在数组中,但在这里,它们在 then 块中。
- 当先前的渲染器不起作用时,他们需要下降到另一个渲染器
- 第一个渲染器与第二个和其他渲染器在某种程度上是相同的算法。它检查结果是否为空。那里有重复。但是,第一个需要先运行,第二个和其他人可以一起运行,他们可以在其中一个returns结果时停止。
let first = $('#id1');
return this.render('priorityRenderer', first).then(isEmpty => {
let els = [
$('#id2'), $('#id3')
];
if (isEmpty) {
// put back the first el to the pool to render it again below
els.unshift(first);
}
return Promise.all(els.map(el => {
return this.render('secondaryRenderer', el)
.then(result => {
if (result) {
return result;
} else {
return this.render('3thRenderer', el)
}
})
.then(result => {
if (result) {
return result;
} else {
return this.render('4thRenderer', el)
}
})
.then(result => {
if (result) {
return result;
} else {
return this.render('5thRenderer', el)
}
});
})
});
您可以使用 中的一个来调用渲染器链,直到第一个 returns 结果:
renderers(rs, el, i=0) {
if (i < rs.length)
return this.render(rs[i], el).then(result => result || this.renderers(rs, el, i+1));
else
return Promise.reject(new Error("no renderer worked, tried: "+rs));
}
然后在你的方法里面,你可以做
let first = $('#id1');
let els = [$('#id2'), $('#id3')];
let rs = ['secondaryRenderer', '3rdRenderer', '4thRenderer', '5thRenderer'];
return Promise.all([
this.renderers(['priorityRenderer'].concat(rs), first)
].concat(els.map(el =>
this.renderers(rs, el)
)));
这是一个经典的回退解决方案。如果第一个 el 没有被渲染,那么它会用其他渲染器重试。如何最好地重构它?
这段代码的问题在于:
- 渲染器需要在数组中,但在这里,它们在 then 块中。
- 当先前的渲染器不起作用时,他们需要下降到另一个渲染器
- 第一个渲染器与第二个和其他渲染器在某种程度上是相同的算法。它检查结果是否为空。那里有重复。但是,第一个需要先运行,第二个和其他人可以一起运行,他们可以在其中一个returns结果时停止。
let first = $('#id1');
return this.render('priorityRenderer', first).then(isEmpty => {
let els = [
$('#id2'), $('#id3')
];
if (isEmpty) {
// put back the first el to the pool to render it again below
els.unshift(first);
}
return Promise.all(els.map(el => {
return this.render('secondaryRenderer', el)
.then(result => {
if (result) {
return result;
} else {
return this.render('3thRenderer', el)
}
})
.then(result => {
if (result) {
return result;
} else {
return this.render('4thRenderer', el)
}
})
.then(result => {
if (result) {
return result;
} else {
return this.render('5thRenderer', el)
}
});
})
});
您可以使用
renderers(rs, el, i=0) {
if (i < rs.length)
return this.render(rs[i], el).then(result => result || this.renderers(rs, el, i+1));
else
return Promise.reject(new Error("no renderer worked, tried: "+rs));
}
然后在你的方法里面,你可以做
let first = $('#id1');
let els = [$('#id2'), $('#id3')];
let rs = ['secondaryRenderer', '3rdRenderer', '4thRenderer', '5thRenderer'];
return Promise.all([
this.renderers(['priorityRenderer'].concat(rs), first)
].concat(els.map(el =>
this.renderers(rs, el)
)));