如何重构这个 promise 回退?

How to refactor this promise fallback?

这是一个经典的回退解决方案。如果第一个 el 没有被渲染,那么它会用其他渲染器重试。如何最好地重构它?

这段代码的问题在于:

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)
)));