اذهب إلى المحتوى

السؤال

نشر

احاول انشاء service عن طريق RxJS و Redux Toolkit ولكن الدالة getProfile لا تعطيني النتيجة المطلوبة.

import { createSlice } from "@reduxjs/toolkit"
import { ofType } from "redux-observable"
import { Observable, of } from "rxjs"
import { catchError, map, switchMap } from "rxjs/operators"

import APIService from "./api.service"

const initialState = {
	profile: null,
	authenticated: false
}

const userSlice = createSlice({
	name: "user",
	initialState,
	reducers: {
		getProfileSuccess: (state, action) => ({
			...state,
			profile: action.payload,
			authenticated: true
		})
	}
})

// ???
const getProfile = (actions) => (
	actions.pipe(
		switchMap(() => {
			APIService.getProfile().pipe(
				map(res => getProfileSuccess(res))
			)
		})
	)
)

 

Recommended Posts

  • 0
نشر

دعنا نأخذ هذه الدالة قطعة بقطعة ونشرح ماذا يحدث بها. تحتوي مكتبة RxJS على ثلاثة مفاهيم رئيسية:

  • الملاحظ (Observable) وهو المكون الأساسي في المكتبة الذي تتعامل معه العمليات والملاحظين.
  • العمليات (operators) مثل switchMap و map.
  • الاشتراكات (Subscriptions)

الملاحظ هو كائن يمكن للملاحظين عمل اشتراك له، ورؤية القيم التي بداخله. اكثر شئ مهم عند استخدام RxJS هو التحكم في حركة القيمة بداخل العمليات بشكلٍ صحيح حتى لا يحدث خلل في النتيجة. لهذا السبب، تأتي المكتبة بالكثير من العمليات لتوفير كل شئ تحتاجه.

مثال بسيط:

// قم بصناعة ملاحَظ
const color = new rxjs.Subject('Red');

// ملاحِظ
function logColorName(color) {
	console.log(`The color has changed to: ${color}.`);
}

// قم بربط الملاحِظ بداخل الملاحَظ
color.subscribe(logColorName);

// الآن عند تغير قيمة اللون ستقوم الدالة بالعمل
color.next('Green'); // => 'The color has changed to: Green'

او مثلاً يمكننا عمل subscribe لحدث الضغط على الشاشة، ولكن عليك استخدام pipe او الانبوب، وهو عبارة عن انبوب تمرر به كل العمليات التي ستقوم بعمل شئ معين على القيمة. هنا مثلاً سنقوم بعمل map على الـ event ونأخذ الـ X axis.

const clicks = fromEvent(window, 'click');

// سنقوم بجمع كل الاماكن التي يتم الضغط عليها على الشاشة
const positions = clicks.pipe(map(event => {
	return event.clientX;
}));

// قم بطباعة الاماكن
positions.subscribe(console.log);

لاحظ ان map تقوم بعمل نفس الشئ في Array.prototype.map فهي تقوم بعمل Loop على كل القيم، ولكن switchMap ستقوم بارجاع احدث قيمة فقط، وتقوم بالتمرير للملاحظ القادم لنستطيع عمل اشتراك او تحويله لـ Promise عن طريق toPromise مثلاً.

لذلك يجب استخدام switchMap بهذا الشكل:

const getProfile = (actions) => (
	actions.pipe(
		// لاحظ هنا اننا نقوم بارجاع القيمة، وليس فقط مناداة الدالة
		switchMap(() => APIService.getProfile().pipe(
			map(res => getProfileSuccess(res))
		))
	)
)

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...