🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
异步调用 === 概述 --- 一般情况下,服务端调用API需要等待插件内部执行完成后,才能进行下一步操作。引入异步调用机制,使服务端可以直接跳过等待,由插件在后台执行,而服务端继续进行下一步操作,只需要等待插件执行完成后进行回调,或服务端主动查询调用结果,也可以忽略调用结果。 对于任意API,**均支持被异步调用**。 使用方法 --- 例如: 调用API`发送私聊消息「sendPrivateMsg」` ```json { "module":"api", "fun": "sendPrivateMsg", "qq": 12345, "msg": "gg" } ``` * 您可以指定参数`async`为`true`,即 ```json { "async": true, "module":"api", ··· } ``` * 也可以在方法名末尾添加`Async`,即 ```json { "module":"api", "fun": "sendPrivateMsgAsync", ··· } ``` 插件将不会直接返回调用结果 ```json { "status": 0, "result": 479, "request": { ··· } } ``` 而是返回用于**查询调用结果的标识符`asyncID`**,并且状态码(`status`)恒为`0`(success) ```json { "status": 0, "asyncID": 6469864, "request": { ··· } } ``` 您也可以指定参数`async`为自定义标识符,如 ```json { "async": 2333, "module":"api", ··· } ``` 但**不建议这样做**,因为在调用结果被服务端取回前,每个标识符都是唯一的,也就是存在冲突。 因此,在标识符产生冲突后,插件会强制生成唯一的随机标识符。 获取调用结果 --- 对于任意的异步调用,插件会保留调用结果以供查询, 您可调用`async`模块下的`get`方法,使用标识符作为参数`id`的值获取调用结果 ```json { "module": "async", "fun": "get", "id": 6469864 } ``` 如果获取成功,状态码(`success`)为`0`,并且响应(`response`)的值为调用结果,该值与通过非异步方式调用结果一致。 ```json { "status": 0, "response": { "status": 0, "result": 478, "request": { ··· } }, "request": { "module": "async", "fun": "get", "id": 6469864 } } ``` 忽略调用结果 --- 您可以选择不查询调用结果,这并不会有任何影响,但强烈建议您在**调用时指定参数`nonCall`为`true`**, ```json { "fun": "sendPrivateMsgAsync", "nonCall": true, ··· } ``` 这样插件就不会申请资源用于存储调用结果。 将调用结果回调 --- 如果您不想服务端主动查询调用结果,也可**指定参数`callback`为回调URL**。 ```json { "fun": "sendPrivateMsgAsync", ··· "callback": "http://example.com/callback" } ``` 调用完成后,插件会使用HTTP协议的**POST方法**将调用结果回传给指定的URL。 ``` POST /callback HTTP/1.1 Cache-Control: no-cache Connection: Keep-Alive Content-Type: application/json; charset=UTF-8 Accept: application/json Accept-Charset: utf-8 Accept-Language: zh-cn User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) Content-Length: 287 Host: example.com { "status": -23, "errmsg": "找不到与目标QQ的关系,消息无法发送", "asyncID": 44482768, "request": { ··· } } ``` 如您所见,**回调数据为`json`格式,`UTF-8`编码,并未进行`URL`编码**,和非异步调用结果相似,仅仅是多了`asyncID`。 您也可**在`callback`中指定更多参数**,以适应不同的业务场景。 ```json { "fun": "sendPrivateMsgAsync", ··· "callback": {         "url": "http://example.com/callback",         "header": "X-Token: This is value.\nX-Forward-To: db.local",         "cookie": "a=b; b=c; c=d",         "proxy": "127.0.0.1:8888", "paramA": "valueA", "paramB": "valueB"     } } ``` | 参数 | 可选 | 说明 | | :-: | :-: | --- | | `url` | **×** | 回调URL | | `header` | √ | HTTP请求头部,多个值请用`\n`换行 | | `cookie` | √ | HTTP请求Cookie | | `proxy` | √ | 代理地址,格式:`ip:port` | **其余参数将作为URL参数进行传递**, > 本示例中存在参数`paramA`与`paramB`, > 因此最终请求的URL为`http://example.com/callback?paramA=valueA&&paramB=valueB`。 对于主动连接 --- > 在本小节,主动连接特指**插件通过HTTP协议向服务端发送数据**的连接行为。 在主动连接中异步调用API并无特殊之处,但因为其可一次调用多条API命令,所以**指定参数`async`为自定义标识符时尤其需要注意其唯一性**。当然,如果标识符不唯一,插件同样会生成一个唯一标识符,但如果服务端在回调时依赖该自定义标识符,则您需要特别注意这点。 如果在一条API命令中**指定`callback`参数**,即设置回调URL,则后续调用的**所有命令都会进行回调**,您可指定参数`nonCall`解除回调。 一些补充 --- * 异步调用主要用于设置操作(即`set`、`send`开头的API), 对于用于获取数据(即`get`开头的API),尽可能不使用异步调用,除非设置回调URL回传数据,否则这种操作是无意义。 * 如果**指定参数`callback`或`nonCall`**,则视为异步调用,无论是否指定参数`async`。