重构以下javascript代码的任何好建议?

时间:2016-06-11 11:48:36

标签: javascript refactoring polymer frontend

有关更简洁的方法来重构此代码的任何想法或建议吗?

也许是循环解决方案或类似的东西?

this._featuredImage = '../../../../../../../../content/images/' + this.post.slug + '.jpg';
this._checkImage(this._featuredImage, function() { // Image exists
  this.featuredImage = this._featuredImage;
}.bind(this), function() { // Image doesn't exist
  this._featuredImage = '../../../../../../../../content/images/' + this.post.slug + '.png';
  this._checkImage(this._featuredImage, function() { // Image exists
    this.featuredImage = this._featuredImage;
  }.bind(this), function() { // Image doesn't exist
    this._featuredImage = '../../../../../../../../content/images/' + this.post.datestamp + '.jpg';
    this._checkImage(this._featuredImage, function() { // Image exists
      this.featuredImage = this._featuredImage;
    }.bind(this), function() { // Image doesn't exist
      this._featuredImage = '../../../../../../../../content/images/' + this.post.datestamp + '.png';
      this._checkImage(this._featuredImage, function() { // Image exists
        this.featuredImage = this._featuredImage;
      }.bind(this), function() { // Image doesn't exist
        this.featuredImage = false;
      }.bind(this));
    }.bind(this));
  }.bind(this));
}.bind(this));

谢谢,我希望这是有道理的。

4 个答案:

答案 0 :(得分:1)

是的,这是一个循环,但由于您的_checkImage函数是异步的,因此它实际上可以是forwhile

var images = [this.post.slug + '.jpg', this.post.slug + '.png', this.post.datestamp + '.jpg', this.post.datestamp + '.png'];
var index = 0;
setFeaturedImage(this);
function setFeaturedImage(t) {
    if (index < images.length) {
        t._featuredImage = '../../../../../../../../content/images/' + images[index];
        t._checkImage(t._featuredImage,
            function() { // Image exists
              t.featuredImage = t._featuredImage;
            },
            function() { // Image doesn't exist
              ++index;
              setFeaturedImage(t);
            }
        );
    }
}

我不太明白为什么要将正在测试的图像保存为_featuredImage。如果没有必要,我们可以摆脱它:

var images = [this.post.slug + '.jpg', this.post.slug + '.png', this.post.datestamp + '.jpg', this.post.datestamp + '.png'];
var index = 0;
setFeaturedImage(this);
function setFeaturedImage(t) {
    if (index < images.length) {
        var image = '../../../../../../../../content/images/' + images[index];
        t._checkImage(image,
            function() { // Image exists
              t.featuredImage = image;
            },
            function() { // Image doesn't exist
              ++index;
              setFeaturedImage(t);
            }
        );
    }
}

答案 1 :(得分:1)

您可以将this存储在变量中而不是使用Function.prototype.bind

来重构和简化代码
var prefix = '../../../../../../../../content/images/';
var that = this;

function activateImageIfExists(image, elseCall)  {
    var fullImagePath = prefix + image;
    that._checkImage(fullImagePath , function() { that.featuredImage = fullImagePath; }, elseCall);
}

activateImageIfExists(that.post.slug + '.jpg', function() {
    activateImageIfExists(that.post.slug + '.png', function() {
        activateImageIfExists(that.post.datestamp + '.jpg', function() {
            activateImageIfExists(that.post.datestamp + '.png', function() {
                that.featuredImage = false;
            });
        });
    });
});

如果您不需要支持旧版浏览器,可以使用箭头功能

var prefix = '../../../../../../../../content/images/';

var activateImageIfExists = (image, elseCall)  => {
    var fullImagePath = prefix + image;
    this._checkImage(fullImagePath, () =>  this.featuredImage = fullImagePath , elseCall);
}

activateImageIfExists(this.post.slug + '.jpg', () => 
activateImageIfExists(this.post.slug + '.png', () => 
activateImageIfExists(this.post.datestamp + '.jpg', () => 
activateImageIfExists(this.post.datestamp + '.png', () =>  this.featuredImage = false ))));

答案 2 :(得分:1)

我将从更改硬编码字符串和首次复制的代码开始:

this.setFeaturedImage = function(newImage) {

  this.featuredImage = newImage;
}

this.unsetFeatureImage = function() {
  this.featuredImage = false;
}

this.imagesRoot = '../../../../../../../../content/images/';
this.fileExtensions = ['jpg' => '.jpg', 'png' => '.png'];

this.getPostSlugImage = function(extension) {
    return this.imagesRoot + this.post.slug + fileExtensions[extension];
}

this.getPostDatestampImage = function(extension) {
    return this.imagesRoot + this.post.datestamp + fileExtensions[extension];
}

比我改变了对这个对象方法的匿名函数调用。 在这里,我看到该方法在链中失败时调用自己。所以我将它们更改为在失败时调用unsetFeaturedImage并返回false

this.trySetPostSlugJpgImage = function() {
  this._checkImage(this.getPostSlugImage('jpg'), this.setFeaturedImage(this.getPostSlugImage('jpg')).bind(this), unsetFeatureImage.bind(this));
  if(this.featuredImage == false) return false;
}

this.trySetPostSlugPngImage = function() {
  this._checkImage(this.getPostSlugImage('png'), this.setFeaturedImage(this.getPostSlugImage('png')).bind(this), unsetFeatureImage.bind(this));
  if(this.featuredImage == false) return false;
}

this.trySetPostDatestampJpgImage = function() {
  this._checkImage(this.getPostDatestampImage('jpg'), this.setFeaturedImage(this.getPostDatestampImage('jpg')).bind(this), unsetFeatureImage.bind(this));
  if(this.featuredImage == false) return false;
}

this.trySetPostDatestampPngImage = function() {
  this._checkImage(this.getPostDatestampImage('png'), this.setFeaturedImage(this.getPostDatestampImage('png')).bind(this), unsetFeatureImage.bind(this));
  if(this.featuredImage == false) return false;
}

结果我得到了:

if(!this.trySetPostSlugJpgImage())
  if(!this.trySetPostSlugPngImage())
    if(!this.trySetPostDatestampJpgImage())
      if(!this.trySetPostDatestampPngImage())

我们可以使用简单的名称关闭功能并在我们的系统中使用

答案 3 :(得分:0)

const path = '../../../../../../../../content/images/';
const images = [
    path + this.post.slug + '.jpg',
    path + this.post.slug + '.png',
    path + this.post.datestamp + '.jpg',
    path + this.post.datestamp + '.png',
];
const c1 = () => this.featuredImage = this._featuredImage;
const c2 = () => {
    let box = images.shift();
    this._featuredImage = box;
    this._checkImage(box, c1, box? c2 : () => {
        this.featuredImage = false;
    });
};

c2();