LuaCoroutine&Promise

LuaCoroutine

Lua 協同程序(coroutine)與線程比較相似:擁有獨立的堆棧,獨立的局部變量,獨立的指令指針,同時又與其它協同程序共享全局變量和其它大部分東西。html

適用場景:git

  • 網絡請求
  • IO操做

一個栗子

-- 建立一個coroutine
co = coroutine.create(function ()
  print("hello coroutine")
end)
print(co) -- thread: 0x00021d68
print(coroutine.status(co)) -- suspended 未被執行或者執行中提示掛起suspended
coroutine.resume(co)        -- hello coroutine  執行
print(coroutine.status(co))  -- dead 執行以後變爲dead狀態
複製代碼

Coroutine一共有3種狀態github

  • dead結束
  • suspend掛起
  • running 執行中

6個方法:promise

  • create

建立coroutine,返回coroutine, 參數是一個函數,當和resume配合使用的時候就喚醒函數調用bash

  • resume

重啓coroutine,和create配合使用網絡

  • yield

掛起coroutine,將coroutine設置爲掛起狀態,這個和resume配合使用能有不少有用的效果異步

  • status

查看coroutine的狀態 注:coroutine的狀態有三種:dead,suspend,running,具體何時有這樣的狀態請參考下面的程序函數

  • wrap

建立coroutine,返回一個函數,一旦你調用這個函數,就進入coroutine,和create功能重複ui

  • running

返回正在跑的coroutine,一個coroutine就是一個線程,當使用running的時候,就是返回一個corouting的線程號lua

更多的栗子

-- Yield栗子

co_func =   function() -- 聲明一個支持yield的函數
                for i = 1,3 do
                    print("co",i)
                    coroutine.yield() -- 設爲掛起狀態
                end
                print("函數結束")
            end

co = coroutine.create(co_func)
coroutine.resume(co) -- 1
coroutine.resume(co) -- 2
print(coroutine.status(co)) -- suspended 執行中爲掛起狀態
coroutine.resume(co) -- 3
coroutine.resume(co) -- "函數結束"

print(coroutine.status(co)) -- dead 整個函數執行完畢
print(coroutine.resume(co)) -- false	cannot resume dead coroutine 結束的coroutine再被執行會報這個錯誤
複製代碼

-- coroutine return的栗子

co = coroutine.create(function(a,b,c)
  print("co",a,b,c)
end)
coroutine.resume(co,1,2,3) -- 多餘的參數會傳遞給coroutine中main函數中

co = coroutine.create(function (a,b)
  coroutine.yield(a+b,a-b)
end)
print(coroutine.resume(co,20,10)) -- yield除了返回true以外,還會返回參數

co = coroutine.create(function()
  print(coroutine.yield())
end)
coroutine.resume(co) -- 由於第一次執行 print執行一半被yield掛起了
coroutine.resume(co,4,5) -- 因此第二次執行纔會執行完整的print

co = coroutine.create(function()
  return 6,7
end)
print(coroutine.resume(co)) -- 當coroutine執行完畢後 return中的參數會返回給resume
複製代碼

-- 生產消費者的栗子

local newProductor

function productor()
     local i = 0
     while true do
          i = i + 1
          send(i)     -- 將生產的物品發送給消費者
     end
end

function consumer()
     while true do
          local i = receive()     -- 從生產者那裏獲得物品
          print(i)
     end
end

function receive()
     local status, value = coroutine.resume(newProductor)
     return value
end

function send(x)
     coroutine.yield(x)     -- x表示須要發送的值,值返回之後,就掛起該協同程序
end

-- 啓動程序
newProductor = coroutine.create(productor)
consumer()
複製代碼

Promise

Promise最大的好處是在異步執行的流程中,把執行代碼和處理結果的代碼清晰地分離了

Promise還能夠作更多的事情,好比,有若干個異步任務,須要先作任務1,若是成功後再作任務2,任何任務失敗則再也不繼續並執行錯誤處理函數。

要串行執行這樣的異步任務,不用Promise須要寫一層一層的嵌套代碼。有了Promise,咱們只須要簡單地寫:

job1.then(job2).then(job3).catch(handleError);
複製代碼

LuaPromise

經過Coroutine能夠很方便的實現相似JS裏Promise的操做

經過使用deferred這個輪子就開發流式的網絡請求了(輪子源碼在文章最後貼出)

deferred = require('./Coroutine/deferred')

function httpGet() -- 模擬網絡請求
  local d = deferred.new()
  local success = true
  if success then
    d:resolve( "success")
  else
    d:reject("error")
  end
  return d
end


-- promise用法
httpGet():next(function(result)
    print(result)
    return result.."option1" -- return數據到下一步
  end):next(function(result)
    print(result)
  end,function(error) -- 只要前面有return reject 就會走最後的error
    print(error)
  end)
複製代碼

相關鏈接:

菜鳥LuaCoroutine教程: http://www.runoob.com/lua/lua-coroutine.html

輪子: https://github.com/zserge/lua-promises

本站公眾號
   歡迎關注本站公眾號,獲取更多信息