简体   繁体   English

如何重构这个承诺后备?

[英]How to refactor this promise fallback?

This is a classic fallback solution. 这是经典的后备解决方案。 If the first el does not get rendered, then it's retrying it with other renderers. 如果第一个el没有得到渲染,则它将与其他渲染器一起重试。 How to best refactor this? 如何最好地重构呢?

What's wrong with this code is that: 这段代码的问题是:

  • Renderers need to be in an array, but here, they're in then blocks. 渲染器需要位于一个数组中,但是在这里,它们位于then块中。
  • They need to fall down to another renderer when the prior renderer didn't work 当先前的渲染器不工作时,它们需要掉落到另一个渲染器
  • The first renderer is kind of the same algo like the 2th and other renderers. 第一个渲染器与第二个渲染器和其他渲染器的算法相同。 It checks whether the result is empty. 它检查结果是否为空。 There is a duplication there. 那里有一个重复项。 But, the first one needs to run first, and the 2nd and others can run together, they can stop whenever one of them returns a result. 但是,第一个需要首先运行,第二个和其他可以一起运行,只要其中一个返回结果,它们就可以停止。
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)
        }
      });
    })
});

You can use one of these approaches to call a chain of renderers until the first one returns a result: 您可以使用以下方法之一来调用渲染器链,直到第一个渲染器返回结果:

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

Then inside your method, you can do 然后在您的方法中,您可以执行

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM