承诺不起作用

时间:2016-12-13 19:48:31

标签: javascript jquery ecmascript-6

我开始学习JS中的Promise。  我写了一个函数,在屏幕上动画显示文字:

function Animal(string) {
    var a = ''; //variable which will be entered character by character string
    var i= 0;//Letter counter
    var p = document.createElement('p');
    $('body').scrollTop($('body').append(p).height());

    Anima();
    function Anima() {//Function of Animation   
        a+=string[i];
        i++;
        $('p').last().text(a);
        var timer = setTimeout(Anima, 100);
        if(i==string.length){
            clearTimeout(timer);
        };
    };
};

我是通过使用回调和显示三个文本字符串视图来编写的,如:

Animal('... ', () =>{                                                   //1
    Animal('---Hello! CONSOLE v 1.0.1 is working!---', () =>{           //2
        Animal('STRING1', () =>{                                    //3                                     
            Animal('STriNG2', () => {                               //4
                Animal('STRING 3', () => {return;})}
        )}
    })
})
});

今天我开始学习Promices。请告诉我,为什么它不起作用?

var Testobj = [
    '1rst string',
    '2ond string',
    '3rd string',
    '4th string'
];

var chain = Promise.resolve();

Testobj.forEach(function(txt) {
  chain = chain
    .then(Animal(txt));
});

PS 以及如何解决它?:)

1 个答案:

答案 0 :(得分:2)

两个问题:

  • Animal函数应该返回一个promise,以确保只有在链中的前一个promise被解析时才会调用then回调。

  • 在向then提供参数时,您可以直接调用 Animal 。相反,您应该传递函数引用。

这是固定代码:

function Animal(string) {
    var a = ''; //variable which will be entered character by character string
    var i= 0;//Letter counter
    var p = document.createElement('p');
    $('body').scrollTop($('body').append(p).height());
    return new Promise(function (resolve) {
        Anima();
        function Anima() {//Function of Animation   
            a+=string[i];
            i++;
            $('p').last().text(a);
            var timer = setTimeout(Anima, 100);
            if(i==string.length){
                clearTimeout(timer);
                resolve();
            };
        };
    });
};        

var Testobj = [
    '1rst string',
    '2ond string',
    '3rd string',
    '4th string'
];

var chain = Promise.resolve();

Testobj.forEach(function(txt) {
  chain = chain.then(Animal.bind(null,txt));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

虽然这样可行,但是你在循环中进行的链接确实是使用reduce的一个很好的选择,这使得它更像函数式编程代码:

Testobj.reduce(function(chain, txt) {
    return chain.then(Animal.bind(null,txt));
}, Promise.resolve());