在图像轮播循环中使用“promise.all”时出现问题

问题描述 投票:0回答:1

这 2 个承诺是: 1-加载下一张图像

Load_Img_p
。 2- 移动到下一张图像之前的等待动画
Timing_Anim_p

它还有一个视觉动画,鼓励您在等待下一张图像完全加载时等待

Hourglass_f

想法是这样的: 并行执行

Timing_Anim_p
Load_Img_p

在解决

Timing_Anim_p
之前,如果出现
Load_Img_p
,则显示
Wait_Img_Load
这是通过一个名为
imgOnLoad

的简单标志来完成的

代码

Load_Img_p

var imgOnLoad = false;

const Load_Img_p = (imgScr ) => new Promise( (resolve ) => 
  {
  imgOnLoad   = true;
  const img   = new Image();
  img.onload  =()=>{ imgOnLoad = false; resolve( img )  };
  img.onerror =()=>{ imgOnLoad = false; resolve( null ) }; 
  img.src     = imgScr;
  })

Hourglass_f
Timing_Anim_p

的原位代码测试

var imgOnLoad = true;  // need also this one to reject other user commands on interface. 

const
  hourglass_elm = document.querySelector('#hourglass')
, Hourglass_f   = (run=false) =>
    {
    hourglass_elm.classList.toggle('showHourglass', run);
    }
, Timing_Anim_e = document.querySelector('#Timing-Anim-bar')
, Timing_Anim_p =()=> new Promise( (resolve ) =>
    {
    Timing_Anim_e.addEventListener('transitionend', ()=>
      {
      Timing_Anim_e.classList.remove('showTiming');
      Hourglass_f(imgOnLoad);
      resolve('Timing_Anim_p ended ok');
      }
      , { once: true }
      );
    Timing_Anim_e.classList.add('showTiming');
    })
    ;

btn_test_A.onclick =_=> Hourglass_f(true);
btn_test_B.onclick =_=> Hourglass_f(false);
btn_test_C.onclick =_=> Timing_Anim_p();
body {
  background-color: #03063a;
  }
#hourglass {
  visibility        : hidden;
  width             : 100px;
  height            : 100px;
  stroke            : #ff146e;
  stroke-dasharray  : 80;
  stroke-dashoffset : 200;
  }
#hourglass.showHourglass {
  visibility : visible;
  animation  : hourglassAnim 1400ms linear infinite alternate;
  }
@keyframes hourglassAnim { to { stroke-dashoffset: 0; } }

#Timing-Anim-bar {
  width    : 500px;
  height   : 10px;
  border   : 1px #9acd32 solid;
  position : relative;
  }
#Timing-Anim-bar::before {
  position   : absolute;
  display    : block;
  top        : 0;
  left       : 0;
  height     : 100%;
  width      : 0%;
  content    : '';  
  background : #0cfa2c;
  }
#Timing-Anim-bar.showTiming::before {
  transition : width 3s linear;
  width      : 100%;
  }
<svg id="hourglass" viewbox="0 0 200 200" class="" >
  <circle id="c5" cx="100" cy="100" r="50" stroke-width="5" fill="transparent" />
</svg>
<div id="Timing-Anim-bar"></div>

<br><br>
<button id="btn_test_A">hourglass true</button>
<button id="btn_test_B">hourglass false</button>
<button id="btn_test_C">test Timing_Anim_p</button>

完成图像更改循环代码,但是不使用promise.ALL:

const 
  img_box = document.querySelector('#img-box')
, imgs_src_list =
    [ 'https://picsum.photos/id/124/400/300.webp'
    , 'https://picsum.photos/id/146/400/300.webp'
    , 'https://picsum.photos/id/155/400/300.webp'
    , 'https://picsum.photos/id/219/400/300.webp'
    ];
var 
  imgOnLoad = false
, img_index = 0;
  ;
const
  hourglass_elm = document.querySelector('#hourglass')
, Hourglass_f   = (run=false) =>
    {
    hourglass_elm.classList.toggle('showHourglass', run);
    }
, Timing_Anim_e = document.querySelector('#Timing-Anim-bar')
, Timing_Anim_p =()=> new Promise( (resolve ) =>
    {
    Timing_Anim_e.addEventListener('transitionend', ()=>
      {
      Timing_Anim_e.classList.remove('showTiming');
      Hourglass_f(imgOnLoad);
      resolve('Timing_Anim_p ended ok');
      }
      , { once: true }
      );
    Timing_Anim_e.classList.add('showTiming');
    })
, Load_Img_p = (imgScr ) => new Promise( (resolve ) => 
    {
    imgOnLoad   = true;
    const img   = new Image();
    img.onload  =()=>{ imgOnLoad = false; resolve( img )  };
    img.onerror =()=>{ imgOnLoad = false; resolve( null ) }; 
    img.src     = imgScr;
    })
, chkBxPlayer = document.querySelector('#chkBx-player')
  ;
chkBxPlayer.addEventListener('change',()=>
  {
  if (chkBxPlayer.checked)
    {
    carousel_Loop();
    }
  else
    {
    Hourglass_f(false);
    Timing_Anim_e.classList.remove('showTiming');
    }
  })
async function carousel_Loop()
  {
  let nxt_src, nxt_imgIdx = img_index
    ;
  while (chkBxPlayer.checked)  
    {
    nxt_imgIdx = ++nxt_imgIdx % imgs_src_list.length;
    nxt_src    = imgs_src_list[nxt_imgIdx];

    await Timing_Anim_p();
    if (!chkBxPlayer.checked) break;

    Hourglass_f(true);
    
    let newImg = await Load_Img_p( nxt_src );

    Hourglass_f(false);

    if (!chkBxPlayer.checked) break;
    if (newImg===null)
      {
      chkBxPlayer.checked = false;
      console.log('Image loading error', nxt_src );
      break;
      }
    img_index = nxt_imgIdx;
    img_box.replaceChildren( newImg );
    }
  Hourglass_f(false); // some security...
  }
body {
  background-color: #03063a;
  }
#img-box, label {
  margin        : 20px;
  border        : 1px whitesmoke solid;
  padding       : 10px;
  width         : fit-content;
  height        : fit-content;
  background    : lightgrey;
  border-radius : 5px;
  position      : relative
  }
#hourglass {
  position    : absolute;
  top         : 50px;
  left        : 50px;
  visibility        : hidden;
  width             : 100px;
  height            : 100px;
  stroke            : #ff146e;
  stroke-dasharray  : 80;
  stroke-dashoffset : 200;
  }
#hourglass.showHourglass {
  visibility : visible;
  animation  : hourglassAnim 1400ms linear infinite alternate;
  }
@keyframes hourglassAnim { to { stroke-dashoffset: 0; } }

#Timing-Anim-bar {
  width    : 500px;
  height   : 10px;
  border   : 1px #9acd32 solid;
  position : relative;
  }
#Timing-Anim-bar::before {
  position   : absolute;
  display    : block;
  top        : 0;
  left       : 0;
  height     : 100%;
  width      : 0%;
  content    : '';  
  background : #0cfa2c;
  }
#Timing-Anim-bar.showTiming::before {
  transition : width 3s linear;
  width      : 100%;
  }
<div id="img-box">
  <img src="https://picsum.photos/id/124/400/300.webp" alt="">
  <svg id="hourglass" viewbox="0 0 220 220" class="">
    <circle cx="110" cy="110" r="50" stroke-width="10" fill="transparent" />
  </svg>
</div>
<div id="Timing-Anim-bar"></div>
<br>
<label> <input type="checkbox" id="chkBx-player" > play diaporama </label>

我尝试过,但循环在第一次更改时停止...:/ 怎么了?

const 
  img_box = document.querySelector('#img-box')
, imgs_src_list =
    [ 'https://picsum.photos/id/124/400/300.webp'
    , 'https://picsum.photos/id/146/400/300.webp'
    , 'https://picsum.photos/id/155/400/300.webp'
    , 'https://picsum.photos/id/219/400/300.webp'
    ];
var 
  imgOnLoad = false
, img_index = 0;
  ;
const
  hourglass_elm = document.querySelector('#hourglass')
, Hourglass_f   = (run=false) =>
    {
    hourglass_elm.classList.toggle('showHourglass', run);
    }
, Timing_Anim_e = document.querySelector('#Timing-Anim-bar')
, Timing_Anim_p =()=> new Promise( (resolve ) =>
    {
    Timing_Anim_e.addEventListener('transitionend', ()=>
      {
      Timing_Anim_e.classList.remove('showTiming');
      Hourglass_f(imgOnLoad);
      resolve('Timing_Anim_p ended ok');
      }
      , { once: true }
      );
    Timing_Anim_e.classList.add('showTiming');
    })
, Load_Img_p = (imgScr ) => new Promise( (resolve ) => 
    {
    imgOnLoad   = true;
    const img   = new Image();
    img.onload  =()=>{ imgOnLoad = false; resolve( img )  };
    img.onerror =()=>{ imgOnLoad = false; resolve( null ) }; 
    img.src     = imgScr;
    })
, chkBxPlayer = document.querySelector('#chkBx-player')
  ;
chkBxPlayer.addEventListener('change',()=>
  {
  if (chkBxPlayer.checked)
    {
    carousel_Loop();
    }
  else
    {
    Hourglass_f(false);
    Timing_Anim_e.classList.remove('showTiming');
    }
  })
async function carousel_Loop()
  {
  let nxt_src, nxt_imgIdx = img_index
    ;
  while (chkBxPlayer.checked)  
    {
    nxt_imgIdx = ++nxt_imgIdx % imgs_src_list.length;
    nxt_src    = imgs_src_list[nxt_imgIdx];

    let resp = await Promise.all([ Timing_Anim_p() , Load_Img_p( nxt_src ) ]);

    Hourglass_f(false);

    let newImg = resp[1];

    if (!chkBxPlayer.checked) break;
 
    if (newImg===null)
      {
      chkBxPlayer.checked = false;
      console.log('Image loading error', nxt_src );
      break;
      }
    img_index = nxt_imgIdx;
    img_box.replaceChildren( newImg );
    }
  Hourglass_f(false); // some security...
  }
body {
  background-color: #03063a;
  }
#img-box, label {
  margin        : 20px;
  border        : 1px whitesmoke solid;
  padding       : 10px;
  width         : fit-content;
  height        : fit-content;
  background    : lightgrey;
  border-radius : 5px;
  position      : relative
  }
#hourglass {
  position    : absolute;
  top         : 50px;
  left        : 50px;
  visibility        : hidden;
  width             : 100px;
  height            : 100px;
  stroke            : #ff146e;
  stroke-dasharray  : 80;
  stroke-dashoffset : 200;
  }
#hourglass.showHourglass {
  visibility : visible;
  animation  : hourglassAnim 1400ms linear infinite alternate;
  }
@keyframes hourglassAnim { to { stroke-dashoffset: 0; } }

#Timing-Anim-bar {
  width    : 500px;
  height   : 10px;
  border   : 1px #9acd32 solid;
  position : relative;
  }
#Timing-Anim-bar::before {
  position   : absolute;
  display    : block;
  top        : 0;
  left       : 0;
  height     : 100%;
  width      : 0%;
  content    : '';  
  background : #0cfa2c;
  }
#Timing-Anim-bar.showTiming::before {
  transition : width 3s linear;
  width      : 100%;
  }
<div id="img-box">
  <img src="https://picsum.photos/id/124/400/300.webp" alt="">

  <svg id="hourglass" viewbox="0 0 220 220" class="" >
    <circle cx="110" cy="110" r="50" stroke-width="10" fill="transparent" />
  </svg>
</div>
<div id="Timing-Anim-bar"></div>
<br>
<label> <input type="checkbox" id="chkBx-player" > play diaporama </label>

javascript css promise es6-promise
1个回答
0
投票

尝试用下面的代码替换,当执行承诺时,“showTiming”在转换结束后立即执行,这样动画就不会重新开始,这只会导致加载一张图像。

setTimeout(() => {
 Timing_Anim_e.classList.add('showTiming')
}, 0);
© www.soinside.com 2019 - 2024. All rights reserved.