Mr.*_*din 3 javascript async-await
我正在尝试构建一种方法来创建可以生成 DOM 事件的生成器。更一般地说,我想创建一种将事件系统转换为产生事件的异步系统的方法。
我的初始代码示例有效,但我可以看到resolve从 Promise 中提升该函数的问题,以便在事件进入后我可以调用该函数。
class EventPropagation {
constructor(id) {
const button = document.getElementById(id);
let _resolve;
button.addEventListener("click", event => {
if (_resolve) {
_resolve(event);
}
});
let _listen = () => {
return new Promise(resolve => {
_resolve = resolve;
});
}
this.subscribe = async function*() {
const result = await _listen();
yield result;
yield * this.subscribe();
}
}
}
async function example() {
const eventPropagation = new EventPropagation("btn");
for await (const event of eventPropagation.subscribe()) {
console.log(event);
}
}
// call the example function
example();
Run Code Online (Sandbox Code Playgroud)
我的问题是:有没有更好的方法来构建这样的东西?有很多事情需要考虑,例如多个事件同时进入或清理侦听器和订阅。我的目标不是最终得到一个反应式库,但我确实想创建异步产生事件的小型透明函数。
2017 年 12 月 14 日编辑(针对 Bergi 的评论进行编辑)
Babel 和一些插件后来;异步生成器不是问题:
const throttle = ms => new Promise(resolve => setTimeout(resolve, ms));
const getData = async() => {
const randomValue = Math.floor(Math.random() * 5000 + 1);
await throttle(randomValue);
return `The random value was: ${randomValue}`;
}
async function* asyncRandomMessage() {
const message = await getData();
yield message;
// recursive call
yield *asyncRandomMessage();
}
async function example() {
for await (const message of asyncRandomMessage()) {
console.log(message);
}
}
// call it at your own risk, it does not stop
// example();
Run Code Online (Sandbox Code Playgroud)
我想知道的是如何将一系列单独的回调调用转换为异步流。我无法想象这个问题没有得到解决。当我查看 Bergi 在评论中显示的库时,我看到了与我相同的实现,即:“将解析和拒绝函数存储在事件处理程序可以调用它们的地方。” 我无法想象这是解决这个问题的正确方法。
小智 9
您需要一个事件存储桶,这是一个示例:
function evtBucket() {
const stack = [],
iterate = bucket();
var next;
async function * bucket() {
while (true) {
yield new Promise((res) => {
if (stack.length > 0) {
return res(stack.shift());
}
next = res;
});
}
}
iterate.push = (itm) => {
if (next) {
next(itm);
next = false;
return;
}
stack.push(itm);
}
return iterate;
}
;(async function() {
let evts = evtBucket();
setInterval(()=>{
evts.push(Date.now());
evts.push(Date.now() + '++');
}, 1000);
for await (let evt of evts) {
console.log(evt);
}
})();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2227 次 |
| 最近记录: |