Просмотр исходного кода

Add promise support to nextTick (#3967)

* add promise support to nextTick

* remove test for non-existent nextTick console error

* Update flow annotation for callback

* Revert flow annotation for nextTick callback
Chris Fritz 9 лет назад
Родитель
Сommit
8bf26536d3

+ 1 - 1
src/core/instance/render.js

@@ -26,7 +26,7 @@ export function initRender (vm: Component) {
 
 export function renderMixin (Vue: Class<Component>) {
   Vue.prototype.$nextTick = function (fn: Function) {
-    nextTick(fn, this)
+    return nextTick(fn, this)
   }
 
   Vue.prototype._render = function (): VNode {

+ 11 - 7
src/core/util/env.js

@@ -87,13 +87,17 @@ export const nextTick = (function () {
   }
 
   return function queueNextTick (cb: Function, ctx?: Object) {
-    const func = ctx
-      ? function () { cb.call(ctx) }
-      : cb
-    callbacks.push(func)
-    if (!pending) {
-      pending = true
-      timerFunc()
+    if (cb) {
+      var func = ctx
+        ? function () { cb.call(ctx) }
+        : cb
+      callbacks.push(func)
+      if (!pending) {
+        pending = true
+        timerFunc()
+      }
+    } else if (typeof Promise !== 'undefined') {
+      return Promise.resolve(ctx)
     }
   }
 })()

+ 17 - 0
test/unit/features/instance/methods-lifecycle.spec.js

@@ -109,5 +109,22 @@ describe('Instance methods lifecycle', () => {
         done()
       })
     })
+
+    if (typeof Promise !== 'undefined') {
+      it('should be called after DOM update in correct context, when using Promise syntax', done => {
+        const vm = new Vue({
+          template: '<div>{{ msg }}</div>',
+          data: {
+            msg: 'foo'
+          }
+        }).$mount()
+        vm.msg = 'bar'
+        vm.$nextTick().then(function (ctx) {
+          expect(ctx).toBe(vm)
+          expect(vm.$el.textContent).toBe('bar')
+          done()
+        })
+      })
+    }
   })
 })

+ 25 - 0
test/unit/modules/util/next-tick.spec.js

@@ -0,0 +1,25 @@
+import { nextTick } from 'core/util/env'
+
+describe('nextTick', () => {
+  it('accepts a callback', done => {
+    nextTick(done)
+  })
+
+  it('returns undefined when passed a callback', () => {
+    expect(typeof nextTick(() => {})).toBe('undefined')
+  })
+
+  if (typeof Promise !== 'undefined') {
+    it('returns a Promise when provided no callback', done => {
+      nextTick().then(done)
+    })
+
+    it('returns a Promise with a context argument when provided a falsy callback and an object', done => {
+      const obj = {}
+      nextTick(undefined, obj).then(ctx => {
+        expect(ctx).toBe(obj)
+        done()
+      })
+    })
+  }
+})