如果我们查看GraphRequestManager.start。
const that = this;
const callback = (error, result, response) => {
if (response) {
that.requestCallbacks.forEach((innerCallback, index, array) => {
if (innerCallback) {
// here it is called as a normal callback, not a generator
innerCallback(response[index][0], response[index][1]);
}
});
}
if (that.batchCallback) {
that.batchCallback(error, result);
}
};
NativeGraphRequestManager.start(this.requestBatch, timeout || 0, callback); } ```
您传递的回调作为普通的Function 调用,而不是GeneratorFunction。
由于它们的执行方式不同,这就是为什么什么都不会发生,因为您的 GeneratorFunction 在被调用时只是被实例化并坐在那里直到被垃圾回收。
因此,与redux-saga 流对齐的解决此问题的首选选项是使用eventChannel,它将流保持在redux-saga 内,实际上是advised for similar cases。
另一个不太可取的方法是只调用原始store.dispatch,它显然突破了redux-saga 的抽象级别和流程,但仍然可以通过调用其他一些saga 操作来完成工作它可以使用response 处理calling 你的startFacebookRegister。
事件频道
我们需要将整个 GraphRequestManager... 块包装到 eventChannel 中,这样我们就可以将 response 或 error 从供应商控制重定向回 saga 流。
可以是这样的:
import {
cancelled,
call,
take,
put
} from "redux-saga/effects";
import {
eventChannel,
END
} from 'redux-saga';
function* startFacebookRegister(err, res) {
const {
id,
email,
first_name,
last_name
} = res;
yield put(initFacebookLogin.success(res));
}
function* graphRequestWrapper() {
return eventChannel(emit => {
const infoRequest = new GraphRequest(
'/me', {
httpMethod: 'GET',
version: 'v2.5',
parameters: {
'fields': {
'string': 'email,first_name,last_name,id'
}
}
}, (err, res) => {
if (err) {
emit(new Error(err));
} else {
emit(res);
}
emit(END);
});
// BTW infoRequest variable should be instantiated before we
// can add it with addRequest, just a side note
new GraphRequestManager().addRequest(infoRequest).start();
return () => {
// clean up
};
})
}
export function* mainSaga() {
const chan = yield call(graphRequestWrapper);
while (true) {
try {
const res = yield take(chan);
yield call(startFacebookRegister, null, res);
} catch (err) {
yield call(startFacebookRegister, err);
} finally() {
if (yield cancelled()) chan.close()
}
}
}
店铺调度
通过 store,您可以从您的 main.js 或 index.js 导出您的 store,您可以在其中将 createStore 与所有减速器和中间件一起使用,并在此处直接使用它。
import store "../exported/from/somewhere";
function* startFacebookRegister({payload}) {
const {
id,
email,
first_name,
last_name
} = payload;
yield put(initFacebookLogin.success(res));
}
function graphRequestWrapper() {
const infoRequest = new GraphRequest(
'/me', {
httpMethod: 'GET',
version: 'v2.5',
parameters: {
'fields': {
'string': 'email,first_name,last_name,id'
}
}
}, (err, response) => {
store.dispatch({type: "INIT_FACEBOOK_LOGIN_REQUEST_SUCCESS_SAGA", payload: {...response}})
});
new GraphRequestManager().addRequest(infoRequest).start();
}
function* mainSaga() {
yield takeLatest("INIT_FACEBOOK_LOGIN_REQUEST_SUCCESS_SAGA", startFacebookRegister);
yield call(graphRequestWrapper);
}