W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
目前我們還沒有講過狀態(tài).如果你的應(yīng)用需要狀態(tài),比如說,來保存你的應(yīng)用設(shè)置,或你需要解讀一個(gè)文件并保存在內(nèi)存中,你該如何存放它們?
最通常的答案是進(jìn)程.我們可以編寫一個(gè)無限循環(huán)的進(jìn)程來保存狀態(tài),收發(fā)信息.例如,讓我們來編寫一個(gè)模塊,內(nèi)容是開啟一個(gè)像鍵值對(duì)一樣運(yùn)作的進(jìn)程,存放在?kv.exs
?文件中:
defmodule KV do
def start_link do
Task.start_link(fn -> loop(%{}) end)
end
defp loop(map) do
receive do
{:get, key, caller} ->
send caller, Map.get(map, key)
loop(map)
{:put, key, value} ->
loop(Map.put(map, key, value))
end
end
end
注意start_link
函數(shù)開啟了一個(gè)運(yùn)行loop/1
函數(shù)的新進(jìn)程,參數(shù)是一個(gè)空映射.loop/1
函數(shù)等待著信息,并且對(duì)每個(gè)信息做出合適的反應(yīng).當(dāng)匹配到:get
信息時(shí),它會(huì)反饋給調(diào)用者一個(gè)信息并再次調(diào)用loop/1
,等待新的信息.當(dāng):put
信息以新版本的映射調(diào)用了loop/1
時(shí),給定的key
和value
就被存儲(chǔ)了.
讓我們?cè)囍\(yùn)行iex kv.exs
:
iex> {:ok, pid} = KV.start_link
#PID<0.62.0>
iex> send pid, {:get, :hello, self()}
{:get, :hello, #PID<0.41.0>}
iex> flush
nil
:ok
一開始,進(jìn)程映射中沒有鍵,所以發(fā)送一個(gè):get
信息,然后刷新當(dāng)前進(jìn)程的收件箱會(huì)得到nil
.讓我們發(fā)送一個(gè):put
信息并再試一次:
iex> send pid, {:put, :hello, :world}
{:put, :hello, :world}
iex> send pid, {:get, :hello, self()}
{:get, :hello, #PID<0.41.0>}
iex> flush
:world
:ok
注意進(jìn)程是如何保存狀態(tài)的,以及我們可以通過向進(jìn)程發(fā)送信息來獲取和更新這個(gè)狀態(tài).事實(shí)上我們可以向任何已知pid
的進(jìn)程發(fā)送信息并操作狀態(tài).
也可以用一個(gè)名字注冊(cè)pid
,并允許任何知道這個(gè)名字的人發(fā)送信息給它:
iex> Process.register(pid, :kv)
true
iex> send :kv, {:get, :hello, self()}
{:get, :hello, #PID<0.41.0>}
iex> flush
:world
:ok
使用進(jìn)程存放狀態(tài),以及名字注冊(cè)在Elixir中都是非常普遍的模式.然而,通常我們不會(huì)像上面那樣手工操作這些模式,而是使用Elixir裝載的一些抽象工具.例如,Elixir提供了代理,它是狀態(tài)的一種簡(jiǎn)單抽象:
iex> {:ok, pid} = Agent.start_link(fn -> %{} end)
{:ok, #PID<0.72.0>}
iex> Agent.update(pid, fn map -> Map.put(map, :hello, :world) end)
:ok
iex> Agent.get(pid, fn map -> Map.get(map, :hello) end)
:world
Agent.start_link/2
可以設(shè)置:name
選項(xiàng),并且會(huì)自動(dòng)注冊(cè).除了代理,Elixir還提供了用于創(chuàng)建通用服務(wù)器(GenServer),任務(wù)等等的API,它們的底層都是由進(jìn)程支持的.我們將在Mix和OTP入門中沿著管理者樹仔細(xì)探索,同時(shí)從頭到尾創(chuàng)建一個(gè)完整的Elixir應(yīng)用.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: