@ikutin

Почему нужно async явно привязывать к контексту?

function Tetris(selector, option) {
    self = this;
    this.container = {
        elem: document.querySelector(selector),
        selector: selector
    };
    this.option = option;
    this.container.elem.style.height = this.option.height + "px";
    this.container.elem.style.width = this.option.width + "px";

    this.cells = {
        width: this.option.width / this.option['block-size'],
        height: this.option.height / this.option['block-size'],
    }
 
    this.getModel=function()
    {
      return  new self.Models();
    }
    this.select = function(x, y) {
     
        let target = m.block(x, y);
      console.log({x,y})
        let oldClass = target.className;
        target.className = oldClass + " select";
        return self;
    }

    this.Models=Models;
    this.fill = async function() {
        let block = function(text=null) {
            let block = document.createElement("div")
            block.className = "cell";
            block.style.height = self.option["block-size"] + "px";
            block.style.width = self.option["block-size"] + "px";
           block.innerHTML=text;
            return block
        }

        await (function() {
            let y = 0;
            let x = 0;
            let count = (self.option.height * self.option.width) / Math.pow(self.option['block-size'], 2);
            for (i = 0; i < count; i++) {
                bl = block();

                if (i != 0 && (i * self.option['block-size']) % self.option.width == 0) {
                    y++;
                    x = 0;
                }
                bl.setAttribute("data-y", y);
                bl.setAttribute("data-x", x);
                self.container.elem.appendChild(bl);
                x++;

            }
        })()

        return self;
    }

   
}



Object.defineProperty(Models.prototype, 'height', {get(){
  return m.position[m.position.length-1].y+1-a.offset.y;
}})
Object.defineProperty(Models.prototype, 'width', {get(){
  return m.position[m.position.length-1].x+1-a.offset.x;
}})
function Models( name) {
    m = this; //*1
    console.log(m,"777");
    this.status = "";
    this.block = function(x, y) {
        return self.container.elem.querySelector(`[data-x='${x}'][data-y='${y}']`);
    }
  this.name=name;
 this.position=[];
   this.action=new Actions();

    this.L = function() {

      m.position= [{
            x: 0,
            y: 0
        }, {
            x: 0,
            y: 1
        }, {
            x: 0,
            y: 2
        }, {
            x: 1,
            y: 2
        }];
        return this;
    }
  
   
    this.show = async function() { //*2
    console.log( m,'mmm')  //*3
     
       await(
            function() {
                 
                m.position.forEach(function(e) {
                 
                  self.select(e.x, e.y)
                });

            })()
    }
return this;


}

function Actions() {
    a = this;

    this.offset={
      x:0,
      y:0
    }

    this.clearActions = async function() {
        let selects = self.container.elem.querySelectorAll(".select:not(.droped)");

        await (
            function() {
                selects.forEach(function(e) {
                  
                    e.className = e.className.replace(/select/, "")
                   e.className = e.className.replace(/s{2,}/g, "")
                })

            })()

    }
    this.left = async function(step) {
        
        if (m.status == "droped") {
            return false;
        }
        await (
            function() {
                a.clearActions().then(function() {
                 
                  m.position = m.position.map(function(e) {
                        
                      
                        return {
                            x: e.x - step,
                            y: e.y
                        };
                    })
                    m.show();
                })
            a.offset.x-=step;
            })()
    }
    this.right = async function(step) {
        if (m.status == "droped") {
            return false;
        }
        await (
            function() {
                a.clearActions().then(function() {
                   console.log(m.position,"111")    
                  m.position = m.position.map(function(e) {
                        
                        return {
                            x: e.x + step,
                            y: e.y
                        };
                    })
                    m.show();
                })
          a.offset.x+=step;
            })()

    }
    this.drop = function() {

        async( function() {
            await(
                function() {
                    d = setInterval(function() {
                        a.clearActions().then(function() {
                            m.position = m.position.map(function(e) {

                                return {
                                    x: e.x,
                                    y: e.y + 1
                                };
                            })
                              a.offset.y++;
                            if (m.position[m.position.length - 1].y == (self.cells.height - 1)) {
                                clearInterval(d);
                                m.position.forEach(function(e) {
                                    let block = m.block(e.x, e.y);
                                    block.className = block.className + " droped";
                                });
                                m.status = "droped";
                            }
                            m.show();
                        })
                    }, self.option.speed)
                })()


        })().then(function() {

        })
        return m;
    }
    this.speedDrop = function() {

    }
    this.rotate = async function(deg) {
      const  CosDeg90=Math.cos(deg*(180/Math.PI));
      const  SinDeg90=Math.sin(deg*(180/Math.PI));
      await (
            function() {
                a.clearActions().then(function() {
                   m.position = m.BasePosition.map(function(e, i) {
                     
                    
                    rx= Math.abs(Math.floor((e.x+5)*CosDeg90+(e.y+5)*SinDeg90));
                    ry=  Math.abs(Math.floor((e.x+5)*SinDeg90+(e.y+5)*CosDeg90));
                      return {
                            x: rx,
                            y: ry
                        };
                    })
                 
                   m.show();
                })
               


            })()


    }
}







tetris = new Tetris(".tetris", {
    "block-size": 20,
    width: 300,
    height: 500,
    speed: 200
})
console.dir(tetris)
var f = new tetris.Models("1"); //*4
f.L();



let f2= new tetris.Models("2");  //*5





tetris.fill().then(function() {
  console.log({f,f2})  
  f.show().then(function(){ //*6
     
    })
})
document.addEventListener("keydown", function(event) {
    if (event.key == "ArrowRight") {
        f.action.right(1);
    }
    if (event.key == "ArrowLeft") {
        f.action.left(1);
    }

})


я объявляю экземпляры объекта в *4 и в *5
в объекте есть position, который описывает координаты квадратов
в первом случае я вызываю L(), который перезаписывает position

во втором случае идет просто объявление экземпляра, то есть f2.position=[]

дальше вызываю f.show() в *6
и дальше в *3 смотрю, что переменная m которая равняется this в *1 , хотя у f2 не вызывался show()

если изменить show в *2 на

this.show = async function(){m=this ....}.bind(this);


то все работает, как должно

отсюда вопрос зачем явно через bind привязывать к контексту, если m ссылается на this?
и стоит ли теперь async функции всегда привязывать через bind(this) ?

буду благодарен за любую информацию
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы