Sagi_Avinash_Varma
Sagi_Avinash_Varma

Reputation: 1509

Trying to understand ES6 Promises: executing three setIntervals sequentially

In order to understand how ES6 Promises I tried to solve this problem statement:

There are three divs: div.red, div.green, and div.blue. They have to appear one after another, each by a setInterval iterative opacity increment (async task).

So the goal is to sequentially execute 3 async tasks.

I have written the following code, This goes into the reject part and gives a TypeError: undefined is not a function {stack: (...), message: "undefined is not a function"}

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style type="text/css">
    div{ width:100px; height:100px; opacity:0; }
    .red{ background:red; }
    .green{ background:green; }
    .blue{ background:blue; }
  </style>
</head>
<body>
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<script type="text/javascript">
    function appear(div){
        console.log("appear");
        console.log(div);
        return new Promise(function(resolve, reject){
            console.log("promise");
            console.log(div.attr("class"));
            var i = 0;
            var loop = setInterval(function(){
                if (i == 1){
                    clearInterval(loop);
                    console.log("animation end");
                    resolve(true);
                }
                div.css({"opacity": i});
                i+=0.1;
            },100);
        });
    }
    $(document).ready(function(){
        var divList = []
        $("div").each(function(){
            divList.push($(this));
        });
        console.log("start");
        (function(){
            return divList.reduce(function(current, next) {
                return appear(current).then(function() {
                    return appear(next);
                }, function(err) { console.log(err); }).then(function() {
                    console.log("div animation complete!")
                }, function(err) { console.log(err); });
            }, Promise.resolve()).then(function(result) {
                console.log("all div animation done!");
            }, function(err) { console.log(err); });
        })();
    });
</script>
</body>
</html>

Upvotes: 0

Views: 426

Answers (1)

Bergi
Bergi

Reputation: 665070

For some reason, you call appear(current). However, current is the promise that represents the current (latest) step of your chain, not the div. It will initially get passed the Promise.resolve(), which is not a jQuery object and does not have an .attr() method.

Instead, use

$(document).ready(function() {
    console.log("start");
    $("div").toArray().reduce(function(currentPromise, nextDiv) {
        return currentPromise.then(function() {
            return appear($(nextDiv));
        });
    }, Promise.resolve()).then(function() {
         console.log("all div animation complete!")
    }, function(err) {
         console.log(err);
    });
});

Upvotes: 1

Related Questions