2016-07-01 6 views
2

なぜこれを後で行うか説明します。 ここに問題があります。予想通り、私はちょうど罰金このようにそれを呼び出すことができます還元状態で約束を返す関数を置きます

const testFunc =() => { 
    return new Promise((resolve, reject) => { 
    setTimeout(() => { 
     if (Math.random() > 0.5) { 
     resolve('succeeded'); 
     } else { 
     reject('failed'); 
     } 
    }, 1000); 
    }); 
}; 

testFunc() 
    .then((result) => console.log(result)) // 'succeeded' 
    .catch((error) => console.log(error)); // 'failed' 

または変数に代入し、この

ようにそれを呼び出す私は以下のような約束を返す関数を持っています
const testFuncVar = testFunc; 
testFuncVar() 
    .then((result) => console.log(result)) // 'succeeded' 
    .catch((error) => console.log(error)); // 'failed' 

これらはすべて予想されます。しかし、いったんredux状態にしてからそこから呼び出すと、もう機能しません。ここに私がしたことがあります(大雑把に単純化)。

const initialState = {testFunc: testFunc}; 
// redux reducer, action creator, etc. 
... 
... 
// somewhere later. Here I'm using redux-thunk to access redux state 
function testFunInState() { 
    return (dispatch, getState) => { 
    const {testFunc} = getState(); 
    // this is not working 
    testFunc() 
     .then((result) => console.log(result)) 
     .catch((error) => console.log(error)); 
    }; 
} 

エラーは_promise2 is not definedです。変数名_promise2はbabel transpilerのものでなければなりません。 I console.log(state.testFunc)またはconsole.log(testFunc)、私が得た場合:

testFunc() { 
    return new _promise2.default(function (resolve, reject) { 
    if (Math.random() > 0.5) { 
     resolve('succeeded'); 
    } else { 
     reject('failed'); 
    } 
    }); 
} 

機能がReduxの状態に置かれるたびだから、何とかPromiseオブジェクトが失われてしまいましたか?

しかし、私は回避策を見つけました。私は

const testFunc = (resolve, reject) => { 
    setTimeout(() => { 
    if (Math.random() > 0.5) { 
     resolve('succeeded'); 
    } else { 
     reject('failed'); 
    } 
    }, 1000); 
}; 

に機能を変更し、resolveとパラメータとして渡さrejectでそれを呼び出す場合は、私は良いですよ。

// this works 
new Promise((resolve, reject) => state.testFunc(resolve, reject)) 
    .then((result) => console.log(result)) 
    .catch((error) => console.log(error)); 

それは約束の作品を返さずにReduxの店が、1に入れていたら、約束を返す関数が動作しない理由を私は思ったんだけど?

私はなぜこのようにしたいのですか?私が達成しようとしているのは、定期的にいくつかの非同期アクションをディスパッチし、結果に応じて(解決または拒否)、何か他のことをやり直す(通知を送信するなど)ジョブキューを持つことです。私は動的にキューに/からジョブを追加/削除したいので、可能なすべてのアクションを処理できるリデューサーを持つことは難しいです。これはそれがそれに近づく合理的な方法だと感じています。私は提案に開放されています。

+0

経由Reduxの状態にtestFuncを追加するためのコードです。..投稿されたコードに? – adeneo

+1

私はあなたが遭遇したバグがこのスニペットに表示されていないと非常に疑います。関数が返すものは問題ではなく、ストアへの参照をストアするだけです。 – AlexG

+0

@adeneo '_promise2'はbable transpilerのものでなければなりません。私はそれをより明確にするために質問を編集しました。 – realbug

答えて

2

を使用して試みることができます私はついにこの問題は還元や約束とは関係がないと考えました。それは単にtestFuncinitialStateオブジェクトリテラルへの代入によってredux状態に追加されているからです。このようにすると、バインディングが失われるため、_promise2 is undefinedというエラーが発生します。実際に、私がtestFuncを還元状態に動的に追加すると(例えば、アクション作成者と還元主体を介して)、バインディングが保持され、すべて正常に機能します。ここに問題https://stackoverflow.com/a/2702028/4401488の詳細な説明があります。

ただ、参考のために、ここで `_promise2` ...何があるように思われないよう、特にエラー、混乱を招く減速

const initialState = {}; 
// redux reducer 
export default function jobReducer(state = initialState, action = {}) { 
    switch (action.type) { 
    case ADD_JOB: 
     return {job: action.job}; 
    default: 
     return state; 
    } 
} 

// action creator 
export function addJob(job) { 
    return { 
    type: ADD_JOB, 
    job: job 
    }; 
} 
... 
// add testFunc to redux state via action creator, 
// I'm using redux-thunk here to access dispatch 
function addTestFun() { 
    return (dispatch) => { 
    dispatch(addJob(testFunc)); 
    }; 
} 
... 
// invocation of testFunc. Here I'm using redux-thunk to access redux state 
function testFunInState() { 
    return (dispatch, getState) => { 
    const {testFunc} = getState(); 
    // Now this is working 
    testFunc() 
     .then((result) => console.log(result)) 
     .catch((error) => console.log(error)); 
    }; 
} 
1

あなたがそのようにのようなあなたの行動を記述するようにRedux Thunk

import { createStore, applyMiddleware } from 'redux'; 
import thunk from 'redux-thunk'; 
import rootReducer from './reducers/index'; 

// Note: this API requires [email protected]>=3.1.0 
const store = createStore(
    rootReducer, 
    applyMiddleware(thunk) 
); 

としてReduxのでミドルウェアを使用する必要があります。

const INCREMENT_COUNTER = 'INCREMENT_COUNTER'; 

function increment() { 
    return { 
    type: INCREMENT_COUNTER 
    }; 
} 

function incrementAsync() { 
    return dispatch => { 
    setTimeout(() => { 
     // Yay! Can invoke sync or async actions with `dispatch` 
     dispatch(increment()); 
    }, 1000); 
    }; 
} 

あなたはまた、もう少し掘りでRedux-Promise

+0

私はreduxサンクを使用しています。しかし、この場合、私の目標は、一連の非同期アクションをディスパッチすることではありません。その代わりに、サンクス(約束を返す関数)を還元状態に動的に追加または削除し、定期的にスケジューラにディスパッチさせたいと思います。 – realbug

+1

ストアは、アプリケーションの状態/データを追跡するためのものであり、関数の格納には使用されません。あなたの店では、サンクを参照するデータ構造を持つことができますし、スケジューラーはあなたの店にあるものに基づいてそれらを呼び出すことができますか? – clhenrick

関連する問題