|
1 |
| -*lua-async-await.txt* For Neovim >= 0.9.4 Last change: 2023 December 10 |
| 1 | +*lua-async-await.txt* For Neovim >= 0.9.4 Last change: 2024 March 31 |
2 | 2 |
|
3 | 3 | ==============================================================================
|
4 | 4 | Table of Contents *lua-async-await-table-of-contents*
|
5 | 5 |
|
6 |
| -1. Lua Async Await |lua-async-await-lua-async-await| |
7 |
| - - Why? |lua-async-await-why?| |
| 6 | +1. Lua Async |lua-async-await-lua-async| |
| 7 | + - What |lua-async-await-what| |
| 8 | + - Why |lua-async-await-why| |
8 | 9 | - How to use |lua-async-await-how-to-use|
|
9 | 10 |
|
10 | 11 | ==============================================================================
|
11 |
| -1. Lua Async Await *lua-async-await-lua-async-await* |
| 12 | +1. Lua Async *lua-async-await-lua-async* |
12 | 13 |
|
13 |
| -This is basically ms-jpq/lua-async-await |
14 |
| -<https://github.com./ms-jpq/lua-async-await> but with Promise like error |
15 |
| -handling |
| 14 | +Synchronous like asynchronous for Lua. |
16 | 15 |
|
17 |
| -Refer the original repository for more comprehensive documentation on how all |
18 |
| -this works |
19 | 16 |
|
| 17 | +WHAT *lua-async-await-what* |
20 | 18 |
|
21 |
| -WHY? *lua-async-await-why?* |
| 19 | +Take a look at before and after |
22 | 20 |
|
23 |
| -A Language Server command response contains two parameters. `error` & |
24 |
| -`response`. If the error is present then the error should be handled. |
25 |
| - |
26 |
| -Ex:- |
| 21 | +**Before:** |
27 | 22 |
|
28 | 23 | >lua
|
29 |
| - self.client.request('workspace/executeCommand', cmd_info, function(err, res) |
| 24 | + request('workspace/executeCommand', cmd_info, function(err, res) |
30 | 25 | if err then
|
31 |
| - log.error(command .. ' failed! arguments: ', arguments, ' error: ', err) |
| 26 | + log.error(err) |
32 | 27 | else
|
33 |
| - log.debug(command .. ' success! response: ', res) |
| 28 | + log.debug(res) |
34 | 29 | end
|
35 | 30 | end, buffer)
|
36 | 31 | <
|
37 | 32 |
|
38 |
| -Promises are fine but chaining is annoying specially when you don’t have |
39 |
| -arrow function like syntactic sugar. Moreover, at the time of this is writing, |
40 |
| -Lua language server generics typing is so primitive and cannot handle |
41 |
| -`Promise<Something>` like types. |
| 33 | +**After:** |
| 34 | + |
| 35 | +>lua |
| 36 | + -- on error, statement will fail throwing an error just like any synchronous API |
| 37 | + local result = request('workspace/executeCommand', cmd_info, buffer) |
| 38 | + log.debug(result) |
| 39 | +< |
| 40 | + |
42 | 41 |
|
43 |
| -So I wanted Promise like error handling but without Promises. |
| 42 | +WHY *lua-async-await-why* |
44 | 43 |
|
| 44 | +Well, callback creates callback hell. |
45 | 45 |
|
46 |
| -HOW TO USE *lua-async-await-how-to-use* |
47 | 46 |
|
48 |
| -Assume following is the asynchronous API |
| 47 | +HOW TO USE *lua-async-await-how-to-use* |
49 | 48 |
|
50 | 49 | >lua
|
51 |
| - local function lsp_request(callback) |
| 50 | + local runner = require("async.runner") |
| 51 | + local wrap = require("async.wrap") |
| 52 | + local wait = require("async.waits.wait_with_error_handler") |
| 53 | + |
| 54 | + local function success_async(callback) |
52 | 55 | local timer = vim.loop.new_timer()
|
53 | 56 |
|
54 | 57 | assert(timer)
|
55 | 58 |
|
56 | 59 | timer:start(2000, 0, function()
|
57 | 60 | -- First parameter is the error
|
58 |
| - callback('something went wrong', nil) |
| 61 | + callback(nil, "hello world") |
59 | 62 | end)
|
60 | 63 | end
|
61 |
| -< |
62 |
| - |
63 |
| - |
64 |
| -WHEN NO ERROR HANDLER DEFINED ~ |
65 |
| - |
66 |
| -This is how you can call this asynchronous API without a callback |
67 |
| - |
68 |
| ->lua |
69 |
| - local M = require('sync') |
70 | 64 |
|
71 |
| - M.sync(function() |
72 |
| - local response = M.wait_handle_error(M.wrap(lsp_request)()) |
73 |
| - end).run() |
74 |
| -< |
75 |
| - |
76 |
| -Result: |
77 |
| - |
78 |
| -> |
79 |
| - Error executing luv callback: |
80 |
| - test6.lua:43: unhandled error test6.lua:105: something went wrong |
81 |
| - stack traceback: |
82 |
| - [C]: in function 'error' |
83 |
| - test6.lua:43: in function 'callback' |
84 |
| - test6.lua:130: in function <test6.lua:129> |
85 |
| -< |
86 |
| - |
87 |
| - |
88 |
| -WHEN ERROR HANDLER IS DEFINED ~ |
89 |
| - |
90 |
| ->lua |
91 |
| - local M = require('sync') |
| 65 | + local function fail_async(callback) |
| 66 | + local timer = vim.loop.new_timer() |
92 | 67 |
|
93 |
| - local main = M.sync(function() |
94 |
| - local response = M.wait_handle_error(M.wrap(lsp_request)()) |
95 |
| - end) |
96 |
| - .catch(function(err) |
97 |
| - print('error occurred ', err) |
| 68 | + assert(timer) |
| 69 | + |
| 70 | + timer:start(2000, 0, function() |
| 71 | + -- First parameter is the error |
| 72 | + callback("something went wrong", nil) |
98 | 73 | end)
|
99 |
| - .run() |
100 |
| -< |
101 |
| - |
102 |
| -Result: |
103 |
| - |
104 |
| -> |
105 |
| - error occurred test6.lua:105: something went wrong |
106 |
| -< |
107 |
| - |
108 |
| - |
109 |
| -WHEN NESTED ~ |
110 |
| - |
111 |
| ->lua |
112 |
| - local M = require('sync') |
| 74 | + end |
113 | 75 |
|
114 |
| - local nested = M.sync(function() |
115 |
| - local response = M.wait_handle_error(M.wrap(lsp_request)()) |
116 |
| - end) |
| 76 | + local function log(message) |
| 77 | + vim.print(os.date("%H:%M:%S") .. " " .. message) |
| 78 | + end |
| 79 | + |
| 80 | + vim.cmd.messages("clear") |
117 | 81 |
|
118 |
| - M.sync(function() |
119 |
| - M.wait_handle_error(nested.run) |
| 82 | + local nested = runner(function() |
| 83 | + local success_sync = wrap(success_async) |
| 84 | + local fail_sync = wrap(fail_async) |
| 85 | + |
| 86 | + local success_result = wait(success_sync()) |
| 87 | + -- here we get the result because there is no error |
| 88 | + log("success_result is: " .. success_result) |
| 89 | + |
| 90 | + -- following is going to fail and error will get caught by |
| 91 | + -- the parent runner function's 'catch' |
| 92 | + wait(fail_sync()) |
120 | 93 | end)
|
| 94 | + |
| 95 | + runner(function() |
| 96 | + log("starting the execution") |
| 97 | + -- just wait for nested runner to complete the execution |
| 98 | + wait(nested.run) |
| 99 | + end) |
121 | 100 | .catch(function(err)
|
122 |
| - print('parent error handler ' .. err) |
| 101 | + log("parent error handler " .. err) |
123 | 102 | end)
|
124 | 103 | .run()
|
125 | 104 | <
|
126 | 105 |
|
127 |
| -Result: |
128 | 106 |
|
129 |
| -> |
130 |
| - parent error handler test6.lua:105: test6.lua:105: something went wrong |
| 107 | +OUTPUT ~ |
| 108 | + |
| 109 | +>txt |
| 110 | + 18:44:46 starting the execution |
| 111 | + 18:44:48 success_result is: hello world |
| 112 | + 18:44:50 parent error handler ...-async-await/lua/async/waits/wait_with_error_handler.lua:14: ...-async-await/lua/async/waits/wait_with_error_handler.lua:14: something went wrong |
131 | 113 | <
|
132 | 114 |
|
133 | 115 | Generated by panvimdoc <https://github.com./kdheepak/panvimdoc>
|
|
0 commit comments