From 00d555b9f41c071f1c455d6ead9f5e1bfcac684a Mon Sep 17 00:00:00 2001 From: Leo Horie Date: Fri, 26 Aug 2016 00:56:01 -0400 Subject: [PATCH] prevent race condition between route.set and async resolve remove path and route from attrs --- api/router.js | 9 ++++----- api/tests/test-router.js | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/api/router.js b/api/router.js index cbf4ab4d..92731e77 100644 --- a/api/router.js +++ b/api/router.js @@ -7,16 +7,15 @@ var autoredraw = require("../api/autoredraw") module.exports = function($window, renderer, pubsub) { var router = coreRouter($window) var route = function(root, defaultRoute, routes) { - var current = {path: null, component: "div"} + var current = {path: null, component: "div", resolver: null}, currentResolutionIdentifier = null var replay = router.defineRoutes(routes, function(payload, args, path, route) { - var resolved = false + var resolutionIdentifier = currentResolutionIdentifier = {} function resolve(component) { - if (resolved) return - resolved = true + if (resolutionIdentifier !== currentResolutionIdentifier) return + resolutionIdentifier = null current.path = path, current.component = component renderer.render(root, payload.render(Vnode(component, null, args, undefined, undefined, undefined))) } - args.path = path, args.route = route if (typeof payload.view !== "function") { if (typeof payload.render !== "function") payload.render = function(vnode) {return vnode} if (typeof payload.onmatch !== "function") payload.onmatch = function() {resolve(current.component)} diff --git a/api/tests/test-router.js b/api/tests/test-router.js index d958ac2e..d62c28b9 100644 --- a/api/tests/test-router.js +++ b/api/tests/test-router.js @@ -240,8 +240,7 @@ o.spec("route", function() { matchCount++ o(vnode.attrs.id).equals("abc") - o(vnode.attrs.path).equals("/abc") - o(vnode.attrs.route).equals("/:id") + o(route.get()).equals("/abc") resolve(Component) }, @@ -279,8 +278,7 @@ o.spec("route", function() { matchCount++ o(vnode.attrs.id).equals("abc") - o(vnode.attrs.path).equals("/abc") - o(vnode.attrs.route).equals("/:id") + o(route.get()).equals("/abc") resolve(Component) }, @@ -457,7 +455,7 @@ o.spec("route", function() { $window.location.href = prefix + "/" route(root, "/", { - "/" : { + "/": { onmatch: function(vnode, resolve) { resolve(A) resolve(B) @@ -476,6 +474,33 @@ o.spec("route", function() { done() }, FRAME_BUDGET) }) + + o("calling route.set invalidates pending onmatch resolution", function(done, timeout) { + timeout(100) + + var resolved + $window.location.href = prefix + "/" + route(root, "/a", { + "/a": { + onmatch: function(vnode, resolve) { + setTimeout(resolve, 20) + }, + render: function(vnode) {resolved = "a"} + }, + "/b": { + view: function() {resolved = "b"} + } + }) + setTimeout(function() { + route.set("/b") + + setTimeout(function() { + o(resolved).equals("b") + + done() + }, 30) + }, FRAME_BUDGET) + }) }) }) })