我试图瞄准键盘事件来解决我的承诺,但它不再起作用了。
下面的函数是将我在参数中给出的密钥与用户输入的密钥进行比较:
function compareKey(a, b) {
if (a && b) {
(a == b) ? output("it matched"): output("it did not match");
}
}
以下函数是在用户键入按键后立即执行
compareKey
函数:
function KeyCatcher(a, ck) {
var touche = null;
document.addEventListener("keydown", function(ev) {
if (ev) {
touche = ev.key;
}
})
if (touche != null) {
ck(a, touche);
}
}
在这里我声明一个承诺,它将帮助我等待键盘事件:
var keyBoardEventCatch = function(a) {
output("promise");
return new Promise(function(resolve) {
KeyCatcher(a, resolve);
});
}
var whenRandom = keyBoardEventCatch('a');
这是我执行承诺的地方:
whenRandom
.then(compareKey);
function output(a) {
console.log(a);
}
按照您编写的方式,解析函数永远不会被调用。看看你的 KeyCatcher 函数。您正在添加一个事件侦听器并传递一个要在事件发生时调用的函数。该回调函数之外的所有内容都会立即执行,包括
if (touche != null) {
ck (a, touche);
}
此时,touche 永远为 null,因为回调函数还没有被调用。要解决此问题,请将该代码块移至回调函数中。
您的下一个问题是将捕获的密钥传递给compareKey函数。 Resolve 只接受一个参数,因此您需要更改您的输入。如果要发送多个变量,请传递对象或数组。
function KeyCatcher(a, ck) {
document.addEventListener("keydown", function(ev) {
if (ev && String.fromCharCode(ev.key)==a) {//i think that what KeyCatcher is supposed to do
ck(a,ev.key);
}
});
}
此外,Promise 只能被触发一次,按键可以被频繁按下。所以你可以实现你自己的承诺,例如:
function infinitePromise(creator){
this.res=[];
this.rej=[];
creator(this.resolve,this.reject);
}
infinitePromise.prototype={
res:[],
rej:[],
resolve:function(arg...){
this.res.forEach(func=>func(...arg));
},
reject:function(arg...){
this.rej.forEach(func=>func(...arg));
},
then:function(func){
this.res.push(func);
}
//...
}
所以你可以这样做:
prom=new infinitePromise(function(resolve){ KeyCatcher("a",resolve);});
prom.then(console.log);
function fromEvent<T extends Event>(element: Node, eventName: string): Promise<T> {
return new Promise<T>(resolve => {
element.addEventListener(eventName, (event: Event) => resolve(event as T), {once : true});
});
}
然后你就可以捕获任何事件,这里我捕获了 keydown。
fromEvent<KeyboardEvent>(window.document, 'keydown')
.then((event) => {
console.log('Key down', event);
});
测试在这里