Что является лучшей заменой setTimeout для полной загрузки окна? - PullRequest
0 голосов
/ 11 января 2019

J - объект с различными функциями.

Функции u, t и z должны запускаться, когда g, m и c полностью загружены в окне (как для Интернета, так и для мобильных устройств), что занимает несколько миллисекунд для ответа серверов.

Какой самый быстрый или лучший способ заменить функцию setTimeout (800 мс)?

Спасибо за миллион,

M

J.o({p:'/dir/file-1.txt'});
J.e({
    g:'/dir/file-2.txt',
    m:'/dir/prefix-',
    c:'/dir/prefix-string.txt'
}); // a function that gets a few files with texts or JSON objects
setTimeout(function(){ 
    J.u({g: window['g'],m: window['m'],c: window['c']}); // a function to be run after loading three JSON objects in window
    J.t(window['p'],{t:"two"}); // a function to be run after loading another large JSON object
    J.z({});
}, 800);




// J.o function 
o:function(z){
    var g,h,x=[];

    Object.keys(z).forEach(function(a,b,c){
        window[a]=null;
        x[b]=new XMLHttpRequest();
        url=window.location.origin.concat('/',z[a.toString()]);
        x[b].open("GET",url,true);
        x[b].onreadystatechange=function (z){
            if(x[b].readyState===4){
                if(x[b].status===200 || x[b].status==0){
                    window[a]=x[b].responseText;
                }
            }
        }
        x[b].send();
     });
}



// J.e function for styles
e:function(z){
    var w,y,e,ar,x=[];
    Object.keys(z).forEach(function(a,b,c){
        window[a]=null;
        x[a]=new XMLHttpRequest();
        if(a=='m'){
            w=window.innerWidth; /*window size*/
            switch(true) {
                case(w<200):
                    window.y='a1';window.e=0.8; /*tiny*/ 
                    break;
                case(w>=200&&w<=360):
                    window.y='a2';window.e=0.9;/*x small*/
                    break;
                case(w>360&&w<=480):
                    window.y='a3';window.e=1; /*small*/
                    break;
                case(w>480&&w<=768):
                    window.y='a4';window.e=1.1; /*medium*/
                    break;
                case(w>768&&w<=1280):
                    window.y='a5';window.e=1.3; /*large*/
                    break;
                case(w>1280&&w<=1920):
                    window.y='a6';window.e=1.6; /*x large*/
                    break;
                case(w>1920):
                    window.y='a7';window.e=1.9; /*xx large*/
                    break;
                default:
                    window.y='a5';window.e=1.2; /*default size */
                    break;
            }
            url=window.location.origin.concat('/',z[a.toString()],window.y,'.txt');

        } else {
            url=window.location.origin.concat('/',z[a.toString()]);
        }
        x[a].open("GET",url,true);

        x[a].onreadystatechange=function (z){
            if(x[a].readyState===4){
                if(x[a].status===200 || x[a].status==0){
                    window[a]=x[a].responseText;
                }
            }
        }
        x[a].send();
     });
}

1 Ответ

0 голосов
/ 11 января 2019

Вместо этого используйте Promises, а затем вы можете использовать Promise.all, который разрешится, когда все обещания в переданном массиве будут разрешены. Вместо forEach над keys переданного объекта, .map вместо каждого из ключей к Обещанию:

const getProm = (url) => new Promise((resolve, reject) => {
  const x = new XMLHttpRequest();
  x.open("GET", url, true);
  x.onreadystatechange = function() {
    if (x.readyState === 4) {
      if (x.status === 200 || x.status == 0) {
        resolve(x.responseText);
      } else {
        reject(x.status);
      }
    }
  }
});

// J.o function 
o: function(z) {
  var g, h, x = [];
  const proms = Object.keys(z).map(function(a, b, c) {
    window[a] = null;
    x[b] = new XMLHttpRequest();
    const url = window.location.origin.concat('/', z[a.toString()]);
    return getProm(url)
      .then((responseText) => {
        window[a] = responseText;
      });
  });
  return Promise.all(proms);
}

// J.e function for styles
e: function(z) {
  var w, y, e, ar, x = [];
  const proms = Object.keys(z).map(function(a, b, c) {
    window[a] = null;
    if (a == 'm') {
      w = window.innerWidth; /*window size*/
      switch (true) {
        case (w < 200):
          window.y = 'a1';
          window.e = 0.8; /*tiny*/
          break;
        case (w >= 200 && w <= 360):
          window.y = 'a2';
          window.e = 0.9; /*x small*/
          break;
        case (w > 360 && w <= 480):
          window.y = 'a3';
          window.e = 1; /*small*/
          break;
        case (w > 480 && w <= 768):
          window.y = 'a4';
          window.e = 1.1; /*medium*/
          break;
        case (w > 768 && w <= 1280):
          window.y = 'a5';
          window.e = 1.3; /*large*/
          break;
        case (w > 1280 && w <= 1920):
          window.y = 'a6';
          window.e = 1.6; /*x large*/
          break;
        case (w > 1920):
          window.y = 'a7';
          window.e = 1.9; /*xx large*/
          break;
        default:
          window.y = 'a5';
          window.e = 1.2; /*default size */
          break;
      }
      url = window.location.origin.concat('/', z[a.toString()], window.y, '.txt');

    } else {
      url = window.location.origin.concat('/', z[a.toString()]);
    }
    return getProm(url)
      .then((responseText) => {
        window[a] = responseText;
      });
  });
  return Promise.all(proms);
}

Затем вы можете позвонить Promise.all по вызовам J.o и J.e:

Promise.all([
  J.o({p:'/dir/file-1.txt'}),
  J.e({
    g:'/dir/file-2.txt',
    m:'/dir/prefix-',
    c:'/dir/prefix-string.txt'
  })
]).then(() => {
  console.log('All requests have finished');
})
.catch((e) => {
  // handle errors
});

Обратите внимание, что будет более элегантно, если вам удастся переключиться на fetch вместо XMLHttpRequest - fetch уже возвращает Promise, поэтому нет необходимости явно создавать Promise с это:

const getProm = url => fetch(url).then((res => res.text());

Но это не поддерживается в древних браузерах, поэтому для его надежного использования вам также понадобится полифилл.

Если единственная причина, по которой вы присваиваете window[a], заключается в том, чтобы иметь возможность позднее получить доступ к асинхронно возвращаемым значениям, не используйте вместо этого значения, разрешенные Обещаниями. Например:

Promise.all([
  getProm('foo'),
  getProm('bar')
])
.then(([foo, bar]) => {
  // foo and bar are variables which hold the response text for foo and bar
});

В качестве примечания вы можете настоятельно рекомендовать отладку и изменение только кода source , а не минимизированного кода. Минимизированный код - это боль для чтения.

...