简体   繁体   中英

How do I use a promise to chain several setTimeout functions?

I have several setTimeout functions in my applications being called at different times (and some being called at the same time after page load)

I am trying to figure out a way to compress and enhance this code. Below is an example of 3 setTimeout functions I am calling, there are in-fact a lot more in my application:

  setTimeout(function () {
    $('.itemOne').css({
      'visibility': 'visible'
    }).addClass('animated slideInRight animate-duration-100');
  }, 1000);

  setTimeout(function () {
    $('.itemTwo').css({
      'background-color': 'rgba(0, 27, 53, 0.8)',
    });
  }, 1200);

  setTimeout(function () {
    $('.itemThree').css({
      'background-color': 'rgba(136, 211, 192, 0.25)',
    });
  }, 1200);

Is the best way to chain these to use a promise chain to make this code compact and neater? Or is there another way?

Not sure if that's what you wanted. I have created a factory wrapping your logic along with a callback triggered once all promises resolve. Let me know if you need further assistance! Cheers!

function createCssPromise($target, styleObj, timeout) {
  const { newStyle, newClass } = styleObj;

  return new Promise((resolve) => {
    setTimeout(() => {
      if (newStyle) {
        $target.css(newStyle); 
      }
      if (newClass) {
        $target.addClass(newClass);
      }

      resolve();
     }, timeout);
  });
}

const targetObj = $('.itemOne');
const styleObj = { 
  newStyle: { 'visibility': 'visible'}, 
  newClass: 'animated slideInRight animate-duration-100', 
}; 
const timeout = 1000;

const firstPromise = new createCssPromise(targetObj, styleObj, timeout);
const secondPromise... //follow the pattern
const thirdPromise...  // follow the pattern

Promise.all([firstPromise, secondPromise, thirdPromise]
  .then(() => console.log('done!'));

*Promise.all is not natively supported in <= IE11.

Please note that this doesn't answer the exact question about using promises, but inside the question you ask about making the code more compact and neater. You could refactor this quite easily into the following, making all of your calls to timeout one liners:

function applyCssWithTimeout($target, cssToApply, timeout, classesToAdd) {
  setTimeout(function() { 
    $target.css(cssToApply).addClass(classesToAdd);
  }, timeout);
}

applyCssWithTimeout($('.itemOne'), { 'visibility': 'visible' }, 1000, 'animated slideInRight animate-duration-100');
applyCssWithTimeout($('.itemTwo'), { 'background-color': 'rgba(0, 27, 53, 0.8)' }, 1200);
applyCssWithTimeout($('.itemThree'), { 'background-color': 'rgba(136, 211, 192, 0.25)' }, 1200);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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