用代码理解JavaScript中的反应式扩展

用代码理解JavaScript中的反应式扩展,javascript,reactive-programming,Javascript,Reactive Programming,我不熟悉反应式扩展和JavaScript。有人能帮我解开下面的代码吗?这是我的 学习反应扩展 $(文档).ready(函数(){ var mouseDragMe=$(“#mouseDragMe”).context; var mouseMove=Rx.Observable.FromHtmlEvent(mouseDragMe,“mouseMove”); var mouseUp=Rx.Observable.FromHtmlEvent(mouseDragMe,“mouseUp”); var mouse

我不熟悉反应式扩展JavaScript。有人能帮我解开下面的代码吗?这是我的


学习反应扩展
$(文档).ready(函数(){
var mouseDragMe=$(“#mouseDragMe”).context;
var mouseMove=Rx.Observable.FromHtmlEvent(mouseDragMe,“mouseMove”);
var mouseUp=Rx.Observable.FromHtmlEvent(mouseDragMe,“mouseUp”);
var mouseDown=Rx.Observable.FromHtmlEvent(mouseDragMe,“mouseDown”);
var mouseMoves=mouseMove
.Skip(1)
.Zip(鼠标移动,函数(左、右){
返回{x1:left.clientX,
y1:左,克利提,
x2:对,clientX,
y2:right.clientY};
});
var mouseDrags=mouseDown.SelectMany(函数(md){
返回mouseMoves.TakeUntil(mouseUp);
订阅(函数(mouseEvents){
$(“#结果”).html(
“旧的(X:+mouseEvents.x1+“Y:+mouseEvents.y1+”)”+
“新的(X:+mouseEvents.x2+“Y:+mouseEvents.y2+”);
});
});                     
});
我是个菜鸟

有关于这方面的描述。我建议你看看。代码是用C语言编写的,但无论使用哪种编程语言,概念都完全相同

基本上你想了解三件事

  • 将一系列事件概念化为一个序列。就像一个 数组是空间中的一系列数据,事件可以看作是 时间(或运动)中的数据序列
  • 操作员(即
    跳过
    压缩
    选择多个
    直到
  • 订阅语义
  • 在这个场景中,我们有3个源序列
    mouseMove
    mouseUp
    mouseDown

    每次移动鼠标时,
    mouseMove
    序列将推送鼠标坐标值。例如,如果鼠标从屏幕的左上角开始沿对角线向下移动,然后直接穿过屏幕,您可能会看到序列上发布的值,如
    {0,0}
    {10,10}
    {20,10}

    mouseUp
    mouseDown
    发布的值并不有趣,只是它们发布的时间点很有趣

    “拖动”的实际问题要求我们知道何时按下鼠标按钮,以及按下鼠标时鼠标所在位置的增量,以及松开按钮时鼠标所在位置的增量。我们得到这些位置的增量的方法是取最终位置的值减去原始位置的值。更好的是,如果我们可以得到所有中间增量值,这样我们就可以为运动设置动画。如果我们取上面的序列,为了得到运动的增量,我们希望得到原始序列和一个off

    Original { 0, 0}, {10,10}, {20,10}  
    offby1   {10,10}, {20,10}  
    
    这允许我们计算三角洲来计算运动(而不仅仅是位置)

    使用Rx实现这一点的方法是首先使用
    Skip(1)
    跳过一个值。这将创建我们的
    offby1
    序列。接下来,我们要成对地组合值。
    Zip
    函数为我们提供了这一点(更多信息请参见)

    我们可以重写上面的代码

    var mouseMoves = mouseMove
    .Skip(1)
    .Zip(mouseMove, function(left, right) {
        return { x1 : left.clientX,
                 y1 : left.clientY,
                 x2 : right.clientX,
                 y2 : right.clientY };
    });
    
    将来

    一旦我们有了这些对,我们需要应用
    newValue-OldValue=delta
    的简单数学。 这给了我们一个delta序列,它实际上是我们的运动序列

    var offby1 = mouseMove.Skip(1);
    var mouseMoves = offby1.Zip(mouseMove, function(current, last) {
        return { x : current.clientX-last.clientX,
                 y : current.clientY-last.clientY };
    });
    
    现在我们只想在鼠标按下时获取值。为此,我们使用操作符。也就是说,对于源中的每个值,从该源中获取0个或多个值。在本例中,每次发生
    mouseDown
    事件时,我们都希望获得所有增量事件(如
    mouseMoves

    但是,我们只想一直接收它们,直到相应的
    mouseUp
    事件发生。为此,我们
    take,直到
    mouseUp
    事件产生一个值

    var mouseDrags = mouseDown.SelectMany(function(md) {
      return mouseMoves.TakeUntil(mouseUp);
    });
    

    现在我们已经完成了所有这些管道,我们通常将这些移动应用于UI元素的位置/边距/偏移。它出现在示例中,我们只是打印值。

    这里有关于它的描述。我建议你看看。代码是用C语言编写的,但无论使用哪种编程语言,概念都完全相同

    基本上你想了解三件事

  • 将一系列事件概念化为一个序列。就像一个 数组是空间中的一系列数据,事件可以看作是 时间(或运动)中的数据序列
  • 操作员(即
    跳过
    压缩
    选择多个
    直到
  • 订阅语义
  • 在这个场景中,我们有3个源序列
    mouseMove
    mouseUp
    mouseDown

    每次移动鼠标时,
    mouseMove
    序列将推送鼠标坐标值。例如,如果鼠标从屏幕的左上角开始沿对角线向下移动,然后直接穿过屏幕,您可能会看到序列上发布的值,如
    {0,0}
    {10,10}
    {20,10}

    mouseUp
    mouseDown
    发布的值并不有趣,只是它们发布的时间点很有趣

    “拖动”的实际问题要求我们知道何时按下鼠标按钮,以及按下鼠标时鼠标所在位置的增量,以及松开按钮时鼠标所在位置的增量。我们得到这些位置的增量的方法是取最终位置的值减去原始位置的值。更好的是,如果我们可以得到所有中间增量值,这样我们就可以为运动设置动画。如果我们取上面的序列,为了得到运动的增量,我们希望得到原始序列和一个off

    Original { 0, 0}, {10,10}, {20,10}  
    offby1   {10,10}, {20,10}  
    
    这允许我们计算三角洲来计算运动(而不仅仅是位置)

    我们可以实现的方式
    var offby1 = mouseMove.Skip(1);
    var mouseMoves = offby1.Zip(mouseMove, function(current, last) {
        return { x : current.clientX-last.clientX,
                 y : current.clientY-last.clientY };
    });
    
    var mouseDrags = mouseDown.SelectMany(function(md) { return mouseMoves;});
    
    var mouseDrags = mouseDown.SelectMany(function(md) {
      return mouseMoves.TakeUntil(mouseUp);
    });