Skip to content

shallowCopy #5290

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

Closed
lyr613 opened this issue Feb 2, 2020 · 1 comment
Closed

shallowCopy #5290

lyr613 opened this issue Feb 2, 2020 · 1 comment

Comments

@lyr613
Copy link

lyr613 commented Feb 2, 2020

New OperatorFunction:shallowCopy


Scenes

When i use react, like this:

// ob
const [the_npc, set_the_npc] = useState<null | npc>(null)
useEffect(() => {
	const ob = npc_focu$.subscribe(npc => {
		set_the_npc(npc)
	})
	return () => ob.unsubscribe()
}, [])
// change
npc.name = 'new name'
npc_focu$.next(npc)

react view will not update, because old_npc === new_npc.
so i write a new OperatorFunction:shallowCopy,
how use:

npc_focu$.pipe(shallowCopy()))

It can shallow copy map, set, array, object. Other type direct copy.

code

import { OperatorFunction, Observable, Operator, Subscriber } from 'rxjs'

class ShallowCopySubscriber<T> extends Subscriber<T> {
	destination: Subscriber<T>
	constructor(destination: Subscriber<T>) {
		super(destination)
		this.destination = destination
	}

	protected _next(value: T) {
		let result: T = value
		try {
			switch (typeof value) {
				case 'object':
					const tostring = Object.prototype.toString.call(value)
					if (Array.isArray(value)) {
						result = [...value] as any
					} else if (tostring === '[object Object]') {
						result = { ...value }
					} else if (value instanceof Set) {
						result = new Set(value) as any
					} else if (value instanceof Map) {
						result = new Map(value) as any
					}
					break

				default:
					break
			}
		} catch (err) {
			this.destination.error(err)
			return
		}
		this.destination.next(result)
	}
}

class ShallowCopyOperator<T> implements Operator<T, T> {
	call(subscriber: Subscriber<T>, source: any): any {
		return source.subscribe(new ShallowCopySubscriber(subscriber))
	}
}

export function shallowCopy<T>(): OperatorFunction<T, T> {
	return (source: Observable<T>) => source.lift(new ShallowCopyOperator())
}

doc

/**

  • 浅拷贝 shallowCopy

  • 只处理4种数据 only handle:
    • array
    • object
    • set
    • map
  • 其他类型将直接赋值 other types: result = value
  • 示例 example:
  • of([1, 2, 3]).pipe(shallowCopy())

*/

@kwonoj
Copy link
Member

kwonoj commented Feb 2, 2020

Our general recommendation for new feature is trying to make it as user-land operator and discuss upstream to core if those changes need to be included or not. Please refer prior discussions similar to this #4164 (comment) and would like to suggest publish as userland module.

@kwonoj kwonoj closed this as completed Feb 2, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Mar 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants