]> git.ipfire.org Git - thirdparty/vuejs/router.git/commit
feat(router): remove partial Promise from router.go
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 11 Sep 2020 16:23:02 +0000 (18:23 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 11 Sep 2020 16:23:02 +0000 (18:23 +0200)
commit6ed6eee38b59eb0b6dec0bcb7d73e24203e20ba4
treeebf04b950d8674d2b19bd65f5e7b5d222dddce1c
parentb58e0aabbaf303367dd4c0d825e66509b68408fa
feat(router): remove partial Promise from router.go

BREAKING CHANGE: The `router.go()` methods doesn't return anything
(like in Vue 3) anymore. The existing implementation was wrong as it
would resolve the promise for the following navigation if `router.go()`
was called with something that wasn't possible e.g. `router.go(-20)`
right after entering the application would not do anything. Even worse,
the promise returned by that call would resolve **after the next
navigation**. There is no proper native API to implement this
promise-based api properly, but one can write a version that should work
in most scenarios by setting up multiple hooks right before calling
`router.go()`:
```js
export function go(delta) {
  return new Promise((resolve, reject) => {
    function popStateListener() {
      clearTimeout(timeout)
    }
    window.addEventListener('popstate', popStateListener)

    function clearHooks() {
      removeAfterEach()
      removeOnError()
      window.removeEventListener('popstate', popStateListener)
    }

    // if the popstate event is not called, consider this a failure
    const timeout = setTimeout(() => {
      clearHooks()
      reject(new Error('Failed to use router.go()'))
      // It's unclear of what value would always work here
    }, 10)

    setImmediate

    const removeAfterEach = router.afterEach((_to, _from, failure) => {
      clearHooks()
      resolve(failure)
    })
    const removeOnError = router.onError(err => {
      clearHooks()
      reject(err)
    })

    router.go(delta)
  })
}
```
__tests__/router.spec.ts
src/router.ts