在回合制卡牌遊戲中,為了避免玩家故意拖時間影響對手遊戲體驗,通常每回合都會要求在一定時間內完成。但究竟這樣的功能要怎麼在 python 內完成呢?各位看官們請接著看下去吧~
在 python 的 asyncio 出來之前,這個功能還真的想不到要怎麼實現,但自從有了 asyncio 之後,作這個功能就非常方便了。不囉嗦,直接上 code~
import asyncio
# 模擬一個可能需要一段時間的異步函數
async def long_running_function():
await asyncio.sleep(10) # 可根據需要改成其他需要時間進行的操作
return "Success" # 可根據需要改成自己要的回傳值
# 主協程
async def main():
try:
# 設定3秒的超時
result = await asyncio.wait_for(long_running_function(), timeout=3)
print(result)
except asyncio.TimeoutError:
print("Operation timed out!")
# 啟動主協程
asyncio.run(main())
裡面有幾個主要元素:
asyncio.wait_for(coro, timeout)
記得裡面的參數是 long_running_function()
而不是 long_running_function
。筆者當初在接觸這邊的時候也以為這跟 callback_func 一樣是把函式當參數帶進去。但其實我們要帶入的是「呼叫 long_running_function() 產生的協程物件」,可以多看一些 asyncio 相關的小抄 (USD 1$) 幫助自己function withTimeout(ms, promise) {
// 創建一個在特定時間後reject的promise
let timeout = new Promise((resolve, reject) => {
let timer = setTimeout(() => {
clearTimeout(timer);
reject(new Error('Operation timed out!'));
}, ms);
});
// 使用Promise.race競賽兩個promises,返回首先完成的那個
return Promise.race([
promise,
timeout
]);
}
// 模擬一個可能需要一段時間的函數
function longRunningFunction() {
return new Promise(resolve => {
setTimeout(() => {
resolve("Success");
}, 5000); // 此模擬函數將在5秒後完成
});
}
// 主要呼叫
async function main() {
try {
let result = await withTimeout(3000, longRunningFunction()); // 設定3秒的超時
console.log(result);
} catch (error) {
console.error(error.message);
}
}
main();
這裡會發現 js 的實作相對比較簡潔,而且它的 Promise.race() 可以處理更多類型的 promise,不限於 sleep 類型的 promise。然後這邊的 withTimeout() 裡面也是 longRunningFunction()
,多看一些範例之後就會記得要加 () 了
今天插播一個其實也蠻重要的小功能,明天之後我們將會回頭把前面的一塊一塊小積木們組合成完整的專案功能,各位看官們敬請期待~