MartinMalinda / vue-concurrency

A library for encapsulating asynchronous operations and managing concurrency for Vue and Composition API.
https://vue-concurrency.netlify.app/
MIT License
352 stars 15 forks source link

Minor documentation improvements #27

Open mcshaz opened 3 years ago

mcshaz commented 3 years ago

First thank you and well done for making such for a great library

The docs are great, but a few small thoughts on improvements:

Using with typescript

If you are passing a Task down as a property to a child component, you can use the typing

const t = props.modelValue as ReturnType<typeof useTask>

Error handling

if you need to perform error handling within the useTask yielded function, define it on the signal argument first. For example if you were logging all calls to the server.

const componentLog = log.create("MyComponent")
const task = useTask(function*(signal, ){
      signal.pr.then(() => componentLog.info('successfully posted'),
          err=> {
            componentLog.warn('failed post', err)
            return Promise.reject(err)
         })
      yield axios.post(`api/...`)

Cancelation

A bit more info would be great around - what happens to the try/catch block if cancel or cancelAll has been called vs the server returning an error. using the example above

const componentLog = log.create("MyComponent")
const task = useTask(function*(signal, ){
      signal.pr.then(() => componentLog.info('successfully posted'),
          err=> {
            if (err === 'cancel') {
               componentLog.warn('request cancelled by user')
            } else {
               componentLog.error('failed post', err)
            }
            return Promise.reject(err)
         })

Thanks again

MartinMalinda commented 3 years ago

Hey thanks for the feedback, appreciated 👍

ReturnType<typeof useTask> will effectively give you something like Task<any, any>. You can import the Task type directly. Due to the plugin being distributed both for Vue 2 and Vue 3 it can be on two different places right now.

I haven't passed a task via v-model so far. I think it's better to pass explicitly via some named prop.

import { Task } from "vue-concurrency/dist/vue3/src/Task";

// ...

props: {
    task: {
      type: Object as () => Task<any, any[]>,
    },

Regarding the signal.pr.then and signal.pr.catch - that is useful especially if you need to react to task cancellation from within the task itself. From my experience its useful for some kind of generic task utils that can be reused on different places. More clear way seems to me to actually handle this outside:

const save = async () => {
  try {
   await someTask.perform();
 } catch (e) {
  if (e === 'cancel') {
    // usually theres no need to react to cancel
  } else {
   // rethrow, fill some ref...
  }
}
};

But in general if what needs to happen after the task is performed is only some rerendering (no side-effects such as flash message display, redirects and so on) then I'd just rely on the derived state such as task.last.error task.last.isCancelled right in the template.

Hope this helps and thanks for the input.

I'll try to incorporate this in the docs later in some way too.

rudolfbyker commented 3 years ago

Another little issue in the docs, under https://vue-concurrency.netlify.app/cancellation/#cancelation-cascade : The code example does not match with the words right below it.