2
0
Эх сурвалжийг харах

async batch update - first pass

Evan You 12 жил өмнө
parent
commit
5c73a378ac

+ 1 - 0
component.json

@@ -20,6 +20,7 @@
         "src/deps-parser.js",
         "src/filters.js",
         "src/transition.js",
+        "src/batch.js",
         "src/directives/index.js",
         "src/directives/if.js",
         "src/directives/repeat.js",

+ 33 - 0
src/batch.js

@@ -0,0 +1,33 @@
+var utils = require('./utils'),
+    queue, has, waiting
+
+reset()
+
+exports.queue = function (binding, method) {
+    if (!has[binding.id]) {
+        queue.push({
+            binding: binding,
+            method: method
+        })
+        has[binding.id] = true
+        if (!waiting) {
+            waiting = true
+            setTimeout(flush, 0)
+        }
+    }
+}
+
+function flush () {
+    for (var i = 0; i < queue.length; i++) {
+        var task = queue[i]
+        task.binding['_' + task.method]()
+        has[task.binding.id] = false
+    }
+    reset()
+}
+
+function reset () {
+    queue = []
+    has = utils.hash()
+    waiting = false
+}

+ 13 - 1
src/binding.js

@@ -1,3 +1,6 @@
+var batch = require('./batch'),
+    id = 0
+
 /**
  *  Binding class.
  *
@@ -6,6 +9,7 @@
  *  and multiple computed property dependents
  */
 function Binding (compiler, key, isExp, isFn) {
+    this.id = id++
     this.value = undefined
     this.isExp = !!isExp
     this.isFn = isFn
@@ -24,9 +28,13 @@ var BindingProto = Binding.prototype
  */
 BindingProto.update = function (value) {
     this.value = value
+    batch.queue(this, 'update')
+}
+
+BindingProto._update = function () {
     var i = this.instances.length
     while (i--) {
-        this.instances[i].update(value)
+        this.instances[i].update(this.value)
     }
     this.pub()
 }
@@ -36,6 +44,10 @@ BindingProto.update = function (value) {
  *  Force all instances to re-evaluate themselves
  */
 BindingProto.refresh = function () {
+    batch.queue(this, 'refresh')
+}
+
+BindingProto._refresh = function () {
     var i = this.instances.length
     while (i--) {
         this.instances[i].refresh()

+ 0 - 12
src/utils.js

@@ -5,11 +5,6 @@ var config    = require('./config'),
     console   = window.console,
     ViewModel // late def
 
-var defer =
-    window.webkitRequestAnimationFrame ||
-    window.requestAnimationFrame ||
-    window.setTimeout
-
 /**
  *  Create a prototype-less object
  *  which is a better hash/map
@@ -185,12 +180,5 @@ var utils = module.exports = {
         if (!config.silent && console) {
             console.warn(join.call(arguments, ' '))
         }
-    },
-
-    /**
-     * Defer DOM updates
-     */
-    nextTick: function (cb) {
-        defer(cb, 0)
     }
 }

+ 5 - 6
src/viewmodel.js

@@ -1,8 +1,7 @@
 var Compiler   = require('./compiler'),
     utils      = require('./utils'),
     transition = require('./transition'),
-    def        = utils.defProtected,
-    nextTick   = utils.nextTick
+    def        = utils.defProtected
 
 /**
  *  ViewModel exposed to the user that holds data,
@@ -104,7 +103,7 @@ def(VMProto, '$appendTo', function (target, cb) {
     var el = this.$el
     transition(el, 1, function () {
         target.appendChild(el)
-        if (cb) nextTick(cb)
+        if (cb) setTimeout(cb, 0)
     }, this.$compiler)
 })
 
@@ -114,7 +113,7 @@ def(VMProto, '$remove', function (cb) {
     if (!parent) return
     transition(el, -1, function () {
         parent.removeChild(el)
-        if (cb) nextTick(cb)
+        if (cb) setTimeout(cb, 0)
     }, this.$compiler)
 })
 
@@ -125,7 +124,7 @@ def(VMProto, '$before', function (target, cb) {
     if (!parent) return
     transition(el, 1, function () {
         parent.insertBefore(el, target)
-        if (cb) nextTick(cb)
+        if (cb) setTimeout(cb, 0)
     }, this.$compiler)
 })
 
@@ -141,7 +140,7 @@ def(VMProto, '$after', function (target, cb) {
         } else {
             parent.appendChild(el)
         }
-        if (cb) nextTick(cb)
+        if (cb) setTimeout(cb, 0)
     }, this.$compiler)
 })
 

+ 10 - 11
test/unit/specs/viewmodel.js

@@ -217,8 +217,7 @@ describe('UNIT: ViewModel', function () {
 
         var enterCalled,
             leaveCalled,
-            callbackCalled,
-            nextTick = require('vue/src/utils').nextTick
+            callbackCalled
         
         var v = new Vue({
             attributes: {
@@ -254,10 +253,10 @@ describe('UNIT: ViewModel', function () {
             v.$appendTo(parent, cb)
             assert.strictEqual(v.$el.parentNode, parent)
             assert.ok(enterCalled)
-            nextTick(function () {
+            setTimeout(function () {
                 assert.ok(callbackCalled)
                 done()
-            })
+            }, 0)
         })
 
         it('$before', function (done) {
@@ -269,10 +268,10 @@ describe('UNIT: ViewModel', function () {
             assert.strictEqual(v.$el.parentNode, parent)
             assert.strictEqual(v.$el.nextSibling, ref)
             assert.ok(enterCalled)
-            nextTick(function () {
+            setTimeout(function () {
                 assert.ok(callbackCalled)
                 done()
-            })
+            }, 0)
         })
 
         it('$after', function (done) {
@@ -287,10 +286,10 @@ describe('UNIT: ViewModel', function () {
             assert.strictEqual(v.$el.nextSibling, ref2)
             assert.strictEqual(ref1.nextSibling, v.$el)
             assert.ok(enterCalled)
-            nextTick(function () {
+            setTimeout(function () {
                 assert.ok(callbackCalled)
                 next()
-            })
+            }, 0)
 
             function next () {
                 reset()
@@ -299,10 +298,10 @@ describe('UNIT: ViewModel', function () {
                 assert.notOk(v.$el.nextSibling)
                 assert.strictEqual(ref2.nextSibling, v.$el)
                 assert.ok(enterCalled)
-                nextTick(function () {
+                setTimeout(function () {
                     assert.ok(callbackCalled)
                     done()
-                })
+                }, 0)
             }
         })
 
@@ -314,7 +313,7 @@ describe('UNIT: ViewModel', function () {
             assert.notOk(v.$el.parentNode)
             assert.ok(enterCalled)
             assert.ok(leaveCalled)
-            nextTick(function () {
+            setTimeout(function () {
                 assert.ok(callbackCalled)
                 done()
             })