[UniRx] AsyncSubject 소개
AsyncSubject 소개 AsyncSubject
는 Subject 시리즈 중 하나로 비동기 처리를 전문적으로 처리하는 Subject
로 자리잡았다.
행동거지는 자바스크립트Promise
와 사라Future
와 크게 다르지 않다.장래에 하나의 결과만 확정할 때 사용할 수 있는 비동기 처리용Subject
.
UniRxObservable
에서 흐름의 길이는 1~무한 길이에 달한다.
이때 억지로 흐름의 길이를 1에 고정시키기 때문에 AsyncSubject는 Future/Promise
와 완전히 같다는 생각에 기초하여 제작되었다.Observable
는 Future
/Promise
보다 더 높은 개념이라고 할 수 있습니다)
AsyncSubject의 행동
(사진 참조: ReactiveXAsyncSubject
의 행위는 다음과 같다.
(사진 참조: ReactiveX
AsyncSubject
의 행위는 다음과 같다.Promise
의resolve(value)
는 OnNext(value) + OnCompleted
로 분해되어 이렇게 생각하면 이해하기 쉽다.용도
일반적으로 Subscribe 이전에 발행된 On Next는 구독할 수 없습니다.
그러나 이Subject
의 경우 서브스크리브의 타이밍에 상관없이 AsyncSubject가 완성되면 반드시 On Next와 On Compuleted를 받을 수 있다.
이러한 특성 때문에 비동기 처리를 위한 콜백이 매우 적합합니다(즉, Subject는 여기에 사용됩니다).
예: 객체의 초기화 순서 제어
갑자기 불규칙한 예지만 편하니까 소개할게요.
객체 A와 객체 B 두 가지가 있습니다. 반드시 "A→B"순서로 초기화하십시오.
유닛의 경우AsyncSubject
는 스크립트의 실행 순서를 조정해서 실현할 수 있지만'실행 순서에 달려 있다'는 정보는 원본 코드에서 유닛으로 유출되기 때문에 불편하면 사용하고 싶지 않다.
따라서 Script Execution Order
를 사용하여 초기화 순서를 잘 실현해 보세요.
설치 예
Objecta (먼저 초기화하려는 쪽)using UniRx;
using UnityEngine;
namespace AsyncSubjectSample
{
/// <summary>
/// 先に初期化されて欲しい方
/// </summary>
public class ObjectA : MonoBehaviour
{
private AsyncSubject<Unit> _initializedAsyncSubject = new AsyncSubject<Unit>();
public IObservable<Unit> OnInitializedAsync
{
get { return _initializedAsyncSubject; }
}
void Start()
{
Debug.Log("ObjectAのStartが実行されました");
//ここでAの初期化処理
Debug.Log("ObjectAの初期化が終わりました");
//初期化完了通知
_initializedAsyncSubject.OnNext(Unit.Default);
_initializedAsyncSubject.OnCompleted();
}
}
}
ObjectB(A 후 초기화자)using UniRx;
using UnityEngine;
namespace AsyncSubjectSample
{
/// <summary>
/// Aの後に初期化されて欲しい方
/// </summary>
public class ObjectB : MonoBehaviour
{
[SerializeField]
private ObjectA objectA;
void Start()
{
Debug.Log("ObjectBのStartが実行されました");
// Aの初期化完了通知が来たらBを初期化する
// OnInitializedAsyncが既にCompleted済みなら直ちに実行される
objectA.OnInitializedAsync.Subscribe(_ => Initialize());
}
void Initialize()
{
//ここでBの初期化処理
Debug.Log("ObjectBの初期化が終わりました");
}
}
}
결실
using UniRx;
using UnityEngine;
namespace AsyncSubjectSample
{
/// <summary>
/// 先に初期化されて欲しい方
/// </summary>
public class ObjectA : MonoBehaviour
{
private AsyncSubject<Unit> _initializedAsyncSubject = new AsyncSubject<Unit>();
public IObservable<Unit> OnInitializedAsync
{
get { return _initializedAsyncSubject; }
}
void Start()
{
Debug.Log("ObjectAのStartが実行されました");
//ここでAの初期化処理
Debug.Log("ObjectAの初期化が終わりました");
//初期化完了通知
_initializedAsyncSubject.OnNext(Unit.Default);
_initializedAsyncSubject.OnCompleted();
}
}
}
using UniRx;
using UnityEngine;
namespace AsyncSubjectSample
{
/// <summary>
/// Aの後に初期化されて欲しい方
/// </summary>
public class ObjectB : MonoBehaviour
{
[SerializeField]
private ObjectA objectA;
void Start()
{
Debug.Log("ObjectBのStartが実行されました");
// Aの初期化完了通知が来たらBを初期化する
// OnInitializedAsyncが既にCompleted済みなら直ちに実行される
objectA.OnInitializedAsync.Subscribe(_ => Initialize());
}
void Initialize()
{
//ここでBの初期化処理
Debug.Log("ObjectBの初期化が終わりました");
}
}
}
ObjectBのStartが実行されました
ObjectAのStartが実行されました
ObjectAの初期化が終わりました
ObjectBの初期化が終わりました
ObjectAのStartが実行されました
ObjectAの初期化が終わりました
ObjectBのStartが実行されました
ObjectBの初期化が終わりました
이렇게 하면 AsyncSubject
의 집행 순서와 상관없이 Start()
의 순서에 따라 초기화해야 한다.총결산 A → B
는 기타AsyncSubject
에 비해 행동이 다르므로 주의해야 한다.
특히 Rx가 Observable의 흐름 길이를 1에 고정하는 것은 Promisse/Future와 완전히 같은 비동기 처리의 아이디어라고 할 수 있는데, 그 실현 중 하나가 바로 AsyncSubject다.
덤 Subject
랩 만들기 대상이 편하니까 소개해드려요.
Singleusing System;
using UniRx;
namespace UniRxExt
{
/// <summary>
/// 名前がRxJavaのSingleとかぶってるけど動作は違います
/// </summary>
public class Single : IObservable<Unit>, IDisposable
{
private readonly AsyncSubject<Unit> _asyncSubject = new AsyncSubject<Unit>();
private readonly object lockObject = new object();
public void Done()
{
lock (lockObject)
{
if (_asyncSubject.IsCompleted) return;
_asyncSubject.OnNext(Unit.Default);
_asyncSubject.OnCompleted();
}
}
public IDisposable Subscribe(IObserver<Unit> observer)
{
lock (lockObject)
{
return _asyncSubject.Subscribe(observer);
}
}
public void Dispose()
{
lock (lockObject)
{
_asyncSubject.Dispose();
}
}
}
}
사용법
ObjectAusing UniRx;
using UniRxExt;
using UnityEngine;
namespace AsyncSubjectSample
{
/// <summary>
/// 先に初期化されて欲しい方
/// </summary>
public class ObjectA : MonoBehaviour
{
private Single _single = new Single();
public IObservable<Unit> OnInitializedAsync
{
get { return _single; }
}
void Start()
{
Debug.Log("ObjectAのStartが実行されました");
//ここでAの初期化処理
Debug.Log("ObjectAの初期化が終わりました");
//初期化完了通知
// OnNext + OnCompletedをくっつけて呼べるだけ
_single.Done();
}
}
}
Reference
이 문제에 관하여([UniRx] AsyncSubject 소개), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toRisouP/items/1bd2f3b07bf868953178
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Subject
랩 만들기 대상이 편하니까 소개해드려요.Single
using System;
using UniRx;
namespace UniRxExt
{
/// <summary>
/// 名前がRxJavaのSingleとかぶってるけど動作は違います
/// </summary>
public class Single : IObservable<Unit>, IDisposable
{
private readonly AsyncSubject<Unit> _asyncSubject = new AsyncSubject<Unit>();
private readonly object lockObject = new object();
public void Done()
{
lock (lockObject)
{
if (_asyncSubject.IsCompleted) return;
_asyncSubject.OnNext(Unit.Default);
_asyncSubject.OnCompleted();
}
}
public IDisposable Subscribe(IObserver<Unit> observer)
{
lock (lockObject)
{
return _asyncSubject.Subscribe(observer);
}
}
public void Dispose()
{
lock (lockObject)
{
_asyncSubject.Dispose();
}
}
}
}
사용법ObjectA
using UniRx;
using UniRxExt;
using UnityEngine;
namespace AsyncSubjectSample
{
/// <summary>
/// 先に初期化されて欲しい方
/// </summary>
public class ObjectA : MonoBehaviour
{
private Single _single = new Single();
public IObservable<Unit> OnInitializedAsync
{
get { return _single; }
}
void Start()
{
Debug.Log("ObjectAのStartが実行されました");
//ここでAの初期化処理
Debug.Log("ObjectAの初期化が終わりました");
//初期化完了通知
// OnNext + OnCompletedをくっつけて呼べるだけ
_single.Done();
}
}
}
Reference
이 문제에 관하여([UniRx] AsyncSubject 소개), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/toRisouP/items/1bd2f3b07bf868953178텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)