Function.InvokeAfter เรียกใช้ฟังก์ชันหลังจากรอเวลาที่กำหนด นำไปใช้ในการควบคุมความเร็วเรียกข้อมูล API หรือเพิ่มความล่าช้าระหว่างการประมวลผล
=Function.InvokeAfter(function as function, delay as duration) as any
=Function.InvokeAfter(function as function, delay as duration) as any
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| function | function | Yes | ฟังก์ชันที่ไม่มีพารามิเตอร์ (parameterless function) ที่ต้องเรียกใช้ เขียนเป็น lambda expression เช่น () => 42 | |
| delay | duration | Yes | เวลาที่ต้องรอก่อนเรียกใช้ฟังก์ชัน ใช้รูปแบบ #duration(0, 0, 0, seconds) เช่น #duration(0, 0, 0, 2) คือรอ 2 วินาที |
Function.InvokeAfter(() => 42, #duration(0, 0, 0, 2))=Function.InvokeAfter(() => 42, #duration(0, 0, 0, 2))
42 (หลังรอ 2 วินาที)
Function.InvokeAfter(() => Text.Combine({"Hello", "World"}, " "), #duration(0, 0, 0, 1))=Function.InvokeAfter(() => Text.Combine({"Hello", "World"}, " "), #duration(0, 0, 0, 1))
"Hello World" (หลังรอ 1 วินาที)
let FetchData = () => Json.Document(Web.Contents("https://api.example.com/data")), WithDelay = Function.InvokeAfter(FetchData, #duration(0, 0, 0, 3)) in WithDel…let
FetchData = () => Json.Document(Web.Contents("https://api.example.com/data")),
WithDelay = Function.InvokeAfter(FetchData, #duration(0, 0, 0, 3))
in
WithDelay
ข้อมูล JSON จากเซิร์ฟเวอร์ (หลังรอ 3 วินาที)
let URLs = {"url1", "url2", "url3"}, FetchWithDelay = (url) => Function.InvokeAfter( () => Json.Document(Web.Contents(url)), #duration(0, 0, 0, 2) ), Results =…let
URLs = {"url1", "url2", "url3"},
FetchWithDelay = (url) => Function.InvokeAfter(
() => Json.Document(Web.Contents(url)),
#duration(0, 0, 0, 2)
),
Results = List.Transform(URLs, FetchWithDelay)
in
Results
รายชื่อข้อมูล JSON จากทั้ง 3 URL (แต่ละขั้นรอ 2 วินาที)
ผมแนะนำให้ใช้ Function.InvokeAfter เมื่อเรียก API ที่มีข้อจำกัดความถี่ (rate limiting) หรือเมื่อต้องการเพิ่มความล่าช้าระหว่างการส่งข้อมูลเพื่อหลีกเลี่ยงการบล็อก โดยมักใช้ร่วมกับ List.Transform หรือ Table.AddColumn เพื่อประมวลผลข้อมูลหลาย ๆ ชุด
ฟังก์ชันต้องไม่มีพารามิเตอร์ (parameterless function) เขียนเป็น lambda expression เช่น () => 42 หรือ () => Text.Combine(…) ถ้าฟังก์ชันต้องใช้พารามิเตอร์ ผมต้องสร้างฟังก์ชัน wrapper ไว้
ใช่ ต้องใช้ #duration เพื่อระบุเวลารอ รูปแบบคือ #duration(days, hours, minutes, seconds) ตัวอย่างเช่น #duration(0, 0, 0, 2) คือรอ 2 วินาที, #duration(0, 0, 1, 0) คือรอ 1 นาที
ผมคืนค่าผลลัพธ์ของฟังก์ชนที่เรียก ประเภทของค่าขึ้นอยู่กับสิ่งที่ฟังก์ชันนั้นทำ (any type) เช่น ถ้าฟังก์ชันคืนค่าตัวเลข ผมจะคืนค่าตัวเลข ถ้าคืนค่า JSON ผมจะคืนค่า JSON
Function.InvokeAfter ยอมให้เราเรียกใช้ฟังก์ชันไม่มีพารามิเตอร์หลังจากรอเวลาที่กำหนด โดยใช้ duration type ของ Power Query เช่น #duration(0, 0, 0, 2) เพื่อรอ 2 วินาที ฟังก์ชันจะทำงานอย่างอะซิงโครนัสและคืนค่าผลลัพธ์เมื่อเสร็จสิ้น
ที่เจ๋งคือ ผมใช้ Function.InvokeAfter เพื่อควบคุมอัตราการเรียก API ให้ไม่เกินลิมิต โดยเพิ่มความล่าช้าสั้นๆ ระหว่างการร้องขอ ตัวอย่างเช่น เมื่อดึงข้อมูลจาก API ที่มีข้อจำกัดจำนวนการร้องขออายุหนึ่ง ผมแยกการดึงข้อมูลออกเป็นชิ้นเล็กๆ แล้วใช้ Function.InvokeAfter เพื่อรอระหว่างแต่ละครั้ง
ส่วนตัวผม แนะนำให้ใช้ Function.InvokeAfter เมื่อเขียนคิวรี่ที่มีการเรียก API จำนวนมาก เพราะมันช่วยป้องกันการบล็อกหรือข้อผิดพลาด 429 Too Many Requests ได้อย่างมีประสิทธิภาพ 😎