diff --git a/runtime/app.js b/runtime/app.js index 0d89421d4..1654bca79 100644 --- a/runtime/app.js +++ b/runtime/app.js @@ -35,10 +35,14 @@ function select_route(url) { } } -function render(Component, data, scroll) { +let current_token; + +function render(Component, data, scroll, token) { Promise.resolve( Component.preload ? Component.preload(data) : {} ).then(preloaded => { + if (current_token !== token) return; + if (component) { component.destroy(); } else { @@ -83,7 +87,7 @@ function navigate(url, id) { } selected.route.load().then(mod => { - render(mod.default, selected.data, scroll_history[id]); + render(mod.default, selected.data, scroll_history[id], current_token = {}); }); cid = id; diff --git a/test/app/routes/_components/Nav.html b/test/app/routes/_components/Nav.html index 48d894554..d17c64687 100644 --- a/test/app/routes/_components/Nav.html +++ b/test/app/routes/_components/Nav.html @@ -1,10 +1,8 @@ diff --git a/test/app/routes/slow-preload.html b/test/app/routes/slow-preload.html new file mode 100644 index 000000000..f445da618 --- /dev/null +++ b/test/app/routes/slow-preload.html @@ -0,0 +1,11 @@ +

This page should never render

+ + \ No newline at end of file diff --git a/test/common/test.js b/test/common/test.js index c8a0cfa03..b945d7625 100644 --- a/test/common/test.js +++ b/test/common/test.js @@ -208,6 +208,40 @@ function run(env) { assert.ok(scrollY > 0, scrollY); }); + + it('cancels navigation if subsequent navigation occurs during preload', async () => { + await nightmare + .goto(base) + .wait(() => window.READY) + .click('a[href="/slow-preload"]') + .wait(100) + .click('a[href="/about"]') + .wait(100); + + assert.equal( + await nightmare.path(), + '/about' + ); + + assert.equal( + await nightmare.evaluate(() => document.querySelector('h1').textContent), + 'About this site' + ); + + await nightmare + .evaluate(() => window.fulfil({})) + .wait(100); + + assert.equal( + await nightmare.path(), + '/about' + ); + + assert.equal( + await nightmare.evaluate(() => document.querySelector('h1').textContent), + 'About this site' + ); + }); }); describe('headers', () => {