转换一个递归函数成异步执行CPS(JavaScript的) [英] Converting a recursive function into an asynchronous CPS implementation (javascript)

查看:155
本文介绍了转换一个递归函数成异步执行CPS(JavaScript的)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我的功能。

    function duplicate_step_through_highlighted (element_jq, target_jq, char_cb) {
        console.log( element_jq);
        var contents = element_jq.contents();
        for (var i = 0 ; i < contents.length; ++i) {
            // if text node, step
            if (contents[i].nodeType === 3) {
                // insert empty text node
                var new_tn = document.createTextNode('');
                target_jq.append(new_tn);

                // iterate it 
                var text = contents[i].nodeValue;
                for (var j = 0; j < text.length; j++) {
                    char_cb(text[j],new_tn);
                    new_tn.nodeValue += text[j];
                    // *** I want an async delay here *** 
                }
            } else { // type should be 1: element
                // target_jq gets a duplicate element inserted, copying attrs
                var new_elem = $(contents[i].cloneNode(false)).appendTo(target_jq);
                duplicate_step_through_highlighted($(contents[i]),$(new_elem),char_cb);

                // then a recursive call is performed on the newly created element as target_jq
                // and the existing one as element_jq. char_cb is passed in
            }
        }
    }

我在做什么是通过一次重建是一个字符重建一个HTML元素。有一个很好的理由这样做,我想它的视觉效果得到输入了。

What I'm doing is rebuilding an HTML element by reconstructing it one character at a time. There is a good reason for doing this, I want the visual effect of it getting "typed in".

所以,现在有没有延误,所以我的元素获得即时复制。我检查的结果是一致的,但它正变得明显,我认为我可能需要以完全重新编写的功能对我来说,能够把在异步延迟每个字符插入后。

So right now there are no delays so my element gets duplicated instantly. I have checked that the result is consistent, but it is becoming clear to me that I will probably need to completely re-write the functionality in order for me to be able to put in an asynchronous delay after each character is inserted.

我是否需要重新写它,并有一个堆栈,以保持元素中记录我的位置?

Will I need to re-write it and have a stack to keep track of my position within the elements?

推荐答案

您可能想看看我最近的答案此旧之一(的演示),关于如何实现这样的效果。

You might want to have a look at my recent answer or this older one (Demo), on how to implement such an effect.

提示:不要克隆元素融入到新的,只是隐藏他们,让他们出现部分的部分。

Tip: Don't clone the elements into new ones, just hide them and make them appear part-for-part.

此外,它可能是不容易对付的jQuery实例的所有,但本机的DOM元素。所以,是的,重写可能会做:-)我认为这确实需要一个堆栈以及

Also, it might be easier not to deal with jQuery instances at all but native DOM elements. So yes, a rewrite might do :-) And I think it does need a stack as well.

function animate(elements, callback) {
/* get: array with hidden elements to be displayes, callback function */
    var i = 0;
    (function iterate() {
        if (i < elements.length) {
            elements[i].style.display = "block"; // show
            animateNode(elements[i], iterate); 
            i++;
        } else if (callback)
            callback();
    })();
    function animateNode(element, callback) {
        var pieces = [];
        if (element.nodeType==1) {
            while (element.hasChildNodes())
                pieces.push(element.removeChild(element.firstChild));
            setTimeout(function childStep() {
                if (pieces.length) {
                    animateNode(pieces[0], childStep); 
                    element.appendChild(pieces.shift());
                } else
                    callback();
            }, 1000/60);
        } else if (element.nodeType==3) {
            pieces = element.data.match(/.{0,2}/g); // 2: Number of chars per frame
            element.data = "";
            (function addText(){
                element.data += pieces.shift();
                setTimeout(pieces.length
                    ? addText
                    : callback,
                  1000/60);
            })();
        }
    }
}

animate($("#foo").children());

演示在jsfiddle.net

它是如何工作:


  • addText 功能增加了一些字符添加到当前文本节点,并设置一个超时本身 - 动画!如果一切都做,它调用回调功能。

  • childStep 运行在childnode动画,并将自己作为回调,直到没有孩子被留 - 再nvokes的回调功能。

  • 两者一起, animateNode 递归地运行在节点树和动画的textnodes在thier秩序。

  • 迭代函数调用 animateNode (后unhinding他们)上的所有投入要素,通过传递本身回调。毕竟投入要素完成后,它会调用外部回调这是考虑的第二个参数动画

  • The addText function adds some character to the current text node, and sets a timeout for itself - animation! In case everything is done, it invokes the callback function.
  • childStep runs the animation on a childnode, and passes itself as the callback until no children are left - then nvokes the callback function.
  • Both together, animateNode recursively runs over the node tree and animates the textnodes in thier order.
  • the iterate function calls animateNode (after unhinding them) on all input elements, by passing itself as the callback. After all input elements are finished, it invokes the outer callback which is given as the second argument to animate.

这篇关于转换一个递归函数成异步执行CPS(JavaScript的)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆