New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to support return promise for dispatch(EFFECT_ACTION) #175

Closed
sorrycc opened this Issue Oct 19, 2016 · 10 comments

Comments

Projects
None yet
7 participants

@sorrycc sorrycc added the enhancement label Oct 19, 2016

@sorrycc sorrycc changed the title from Try to support return promise to dispatch(EFFECT_ACTION) to Try to support return promise for dispatch(EFFECT_ACTION) Oct 19, 2016

@nickzheng

This comment has been minimized.

nickzheng commented Jan 12, 2017

1.如果我要集成 异步关闭, https://ant.design/components/modal-cn/#components-modal-demo-async, onOk 必须接受一个promise 在then 里面 this.setState({
visible: false,
confirmLoading: false,
});

在dva里面dispatch 一个action 后 ,
dispatch({
type: 'users/create',
payload: values,
}); 的值不是一个promise, 而是一个action 。

  1. 而解决方法可以是把visible,confirmLoading状态放到store里面。

  2. 有没有可能dva里面dispatch 一个action 后 , 是一个promise, redux-thunk 里面是一个promise, 我菜可能是saga 的实现不同吧

@pizn

This comment has been minimized.

pizn commented Feb 22, 2017

@nickzheng 尝试使用这个方法:

在组件里面使用 promise 包装 dispatch,例如:

   new Promise((resolve, reject) => {
      dispatch({
         type: 'users/create',
         payload: {
             values,
             resolve,
             reject,
         },
      }); 
   })
   .then( res => {
      console.log(res);
   })
  .catch( err => {
      console.log(err);
  })

而在 dva 的 effect 里面可以这样写:

* create({ payload }, { put, call }) {
  const { value, resolve, reject } = payload;
  // 一些操作之后

  if (success) {
     resolve('done');
  } else {
     reject('error');
  }
}

@sorrycc 之前的想法是不需要在发起 dispatch 的地方包装一层 promise,而 dva 可以自带这个功能,默认的 effect 可以返回 resolve 和 reject。

@sorrycc

This comment has been minimized.

Member

sorrycc commented Jul 18, 2017

https://github.com/dvajs/dva-core/blob/0fa6888/test/effects-test.js#L332-L365 ,内置支持 dispatch(EffectAction) 返回 Promise 。

@daskyrk

This comment has been minimized.

daskyrk commented Jul 21, 2017

@sorrycc 赞一个,问下这个功能是哪个版本加上去的?好像没看到changelog?

@sorrycc

This comment has been minimized.

Member

sorrycc commented Jul 21, 2017

@sorrycc

This comment has been minimized.

Member

sorrycc commented Sep 2, 2017

It's supported in dva@2 .

@holynova

This comment has been minimized.

holynova commented Jan 13, 2018

请问内置支持promise后, 在effect中如何定义resolve和reject?
怎么算成功, 怎么算失败呢?
@pizn 提供的方案中, 是通过payload把resolve和reject传进effct的, 然后在effect中调用action.payload,resolve

@holynova

This comment has been minimized.

holynova commented Jan 26, 2018

   new Promise((resolve, reject) => {
      dispatch({
         type: 'users/create',
         payload: {
             values,
             resolve,
             reject,
         },
      }); 
   })
   .then( res => {
      console.log(res);
   })
  .catch( err => {
      console.log(err);
  })

内置promise的意思是把上面变成下面么?

dispatch({
  type: 'users/create',
  payload: {
    values,
    resolve,
    reject,
  },
})
  .then(res => {
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  })
@Youthink

This comment has been minimized.

Youthink commented May 9, 2018

project

const { dispatch } = this.props;
dispatch({
   type: 'specification/fetch',
    payload: applicationId,
 }).then((data) => {
     console.log(data)
 });

model

 effects: {
    * fetch({ payload }, { call, put, select}) {
      const response = yield call(querySpecification, payload);
      yield put({
        type: 'list',
        payload: response
      });
      return yield select(state => state.specification.list);  //important
    }
},
reducers: {
    list(state, action) {
      return {
        ...state,
        list: action.payload
      };
    }
  }
@byk04712

This comment has been minimized.

byk04712 commented Aug 31, 2018

@Youthink 像下面我这种情况怎么办

project

this.props.dispatch({
    type: 'app/login',
    payload: {
        phone: '13312332131',
        smscode: '6666',
    }
}).then(data => {
    console.log('success result', data)
}).catch(err => {
    console.warn('error result', err)
})

model

*login({ payload }, { call, put }) {
    // 请求状态 fetching 为 true,方便页面显示loading状态
    yield put({ type: 'updateState', fetching: true })
    // 这里进行登录 service
    const login = yield call(authService.login, payload)
    // 如果上面的 authService.login 异常了,下面的逻辑就不会进行了,下面的 fetching 设置为 false 也不会执行到
    if (login) {
        yield put(NavigationActions.back())
        Storage.set('login', login)
    }
    // 这里重置下 状态 fetching 为 false
    yield put({type:'updateState', fetching: false })
},

我想不管是后端返回成功还是有异常,都能执行到 yield put({type:'updateState', fetching: false }) 。我知道可以在project里,不管是成功还是失败再发一个 dispatch 到 model 里设置fetching,但是感觉这么做似乎不是很妥。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment