Merge pull request #659 from nofficalfs/Dev-GoLikeChannel

Add `lib.channel` to give a method of message receiving.
This commit is contained in:
Spmario233 2023-11-22 22:57:14 +08:00 committed by GitHub
commit 2f5c2320cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 102 additions and 0 deletions

View File

@ -363,6 +363,108 @@ new Promise(resolve=>{
}
}],
},
/**
* **无名杀频道推送机制**
*
* 鉴于`Javascript`的特性及自身对所需功能的思考这是一个参考`Golang``channel`设计的完全和`go channel`不一样的异步消息传递对象
*
* 当且仅当接收方和发送方均存在时进行消息传递完全保证信息传递的单一性发送方/接收方一旦确定则无法更改和准确性发送方必然将消息发送给接收方
*
* 若存在发送方/接收方时调用`send`/`receive`将报错
*
* 若需要异步/不报错发送信息请等待`lib.actor`
*
* @template T
* @example
* // 创建一个频道
* const channel = new lib.channel();
*
* // 从某个角落接收channel发出的消息若无消息则等待
* const message = await channel.receive();
*
* // 从某个角落向channel发消息若无消息接收则等待
* await channel.send(item);
*/
channel: class {
/**
* @template TValue
* @callback PromiseResolve
* @param {TValue} value
* @returns {void}
*/
constructor() {
/**
* @type {"active" | "receiving" | "sending"}
*/
this.status = "active";
/**
* @type {PromiseResolve<T> | [T, PromiseResolve<void>] | null}
*/
this._buffer = null;
}
/**
* 向该频道发送消息在消息未被接受前将等待
*
* @param {T} value - 要发送的消息
* @returns {Promise<void>}
*/
send(value) {
return new Promise((resolve, reject) => {
switch (this.status) {
case "sending":
// TODO: handle the error.
reject(new Error());
break;
case "receiving":
/**
* @type {PromiseResolve<T>}
*/
const buffer = this._buffer;
this._buffer = null;
buffer(value);
this.status = "active";
resolve();
break ;
case "active":
this.status = "sending";
this._buffer = [value, resolve];
break;
}
});
}
/**
* 接收频道所发送的消息若无消息发送则等待
*
* @returns {Promise<T>} 接收到的消息
*/
receive() {
return new Promise((resolve, reject) => {
switch (this.status) {
case "receiving":
// TODO: handle the error.
reject(new Error());
break;
case "sending":
/**
* @type {[T, PromiseResolve<void>]}
*/
const buffer = this._buffer;
this._buffer = null;
resolve(buffer[0]);
this.status = "active";
buffer[1]();
break ;
case "active":
this.status = "receiving";
this._buffer = resolve;
break;
}
});
}
},
/**
* **无名杀消息推送库**
*