最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ES6 promises: how to chain functions with arguments - Stack Overflow

programmeradmin3浏览0评论

How to chain functions with delays. I tried the following:

Promise.resolve()
.then(setKeyframe('keyframe-0'))
.then(delay(3000))
.then(setKeyframe('keyframe-1'))
.then(delay(3000))
.then(setKeyframe('keyframe-2'))
;

function delay(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms);
  });
}

function setKeyframe (name) {
  var element = document.getElementsByClassName('animation-container')[0];
  element.className = 'animation-container ' + name;
}

All functions seem to be called immediately after each other. The delay function does not delay the chain. What am I missing?

How to chain functions with delays. I tried the following:

Promise.resolve()
.then(setKeyframe('keyframe-0'))
.then(delay(3000))
.then(setKeyframe('keyframe-1'))
.then(delay(3000))
.then(setKeyframe('keyframe-2'))
;

function delay(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms);
  });
}

function setKeyframe (name) {
  var element = document.getElementsByClassName('animation-container')[0];
  element.className = 'animation-container ' + name;
}

All functions seem to be called immediately after each other. The delay function does not delay the chain. What am I missing?

Share Improve this question edited Mar 3, 2017 at 17:32 jib 42.6k17 gold badges108 silver badges165 bronze badges asked Apr 14, 2016 at 15:39 SvenSven 6,33824 gold badges77 silver badges116 bronze badges 2
  • 4 You have to pass a callback that returns a promise into then, not a promise itself. – Bergi Commented Apr 14, 2016 at 15:41
  • you're starting all of the actions at once – Kevin B Commented Apr 14, 2016 at 15:42
Add a ment  | 

3 Answers 3

Reset to default 5

Your mistake might be easier to spot with a function without arguments:

The right way:

Promise.resolve().then(setFirstKeyframe)

Above, the function setFirstKeyframe is an argument to .then, for the promise to call later.

The wrong way:

Promise.resolve().then(setFirstKeyframe())

Here, setFirstKeyframe is called immediately (!), and its result (a promise) is passed to then (which gets ignored as then expects a function).

For functions with arguments use an anonymous function:

Promise.resolve().then(function() {
  return setFirstKeyframe('keyframe-0');
})

This is where es6 arrow functions rock:

Promise.resolve().then(() => setFirstKeyframe('keyframe-0'))

.then() accepts a function, which may or may not return a promise

You are however passing a promise directly

// Yes
Promise.resolve().then(() => { return new Promise(); });

// No
Promise.resolve().then(new Promise());

It's because you were calling all functions instead of providing them as handlers.

Promise.resolve('keyframe-0')
.then(setKeyframe)
.then(delay(3000, 'keyframe-1'))
.then(setKeyframe)
.then(delay(3000, 'keyframe-2'))
.then(setKeyframe)
;

function delay(ms, value) {
  return function (val) {
    return new Promise((resolve, reject) => {
      setTimeout(resolve, ms, value !== undefined ? value : val);
    });
  };
}

function setKeyframe(name) {
  var element = document.body;
  element.className = 'animation-container ' + name;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

.keyframe-0 { background: red; }
.keyframe-1 { background: green; }
.keyframe-2 { background: blue; }

发布评论

评论列表(0)

  1. 暂无评论