bounty还有3天到期。回答此问题可获得+50声望奖励。Handsome Nerd希望引起更多关注这个问题。
从一个非常简单的例子开始,要求用户确认一个选择:
let a = function(){ return window.confirm( "Proceed" ); };
let b = function(){ console.log("b: " + a() ); };
let c = function(){ b(); console.log( "after b" ); };
c();
c();
window.confirm()
是一个异步事件,但函数以同步方式运行,并阻止执行,直到它被解决。
将其更改为使用自定义UI,该UI使用await
阻止执行,直到用户响应。但是await
documentation声明:await
运算符用于等待Promise
。它只能在async
函数内部使用。
因此,包含await
表达式的函数必须被设置为async
并返回一个promise,而不是之前的值,现在a()
不会阻塞执行:
let a = async function(){
let conf = document.createElement( "DIV" );
conf.className = 'confirm';
let message = document.createElement( "DIV" );
message.className = 'confirm-message';
message.innerText = 'Proceed';
conf.appendChild( message );
let ok = document.createElement( "BUTTON" );
ok.innerText = 'Ok';
conf.appendChild( ok );
let cancel = document.createElement( "BUTTON" );
cancel.innerText = 'Cancel';
conf.appendChild( cancel );
document.body.appendChild( conf );
let v = await new Promise(
response => {
ok .addEventListener( "click", ()=>{ response(true ); }, false );
cancel.addEventListener( "click", ()=>{ response(false); }, false );
}
);
conf.remove();
return v;
};
let b = function(){ console.log("b: " + a() ); };
let c = function(){ b(); console.log( "after b" ); };
c();
c();
.confirm { display: grid; width: min-content; grid-template-columns: 10em 10em; grid-gap: 0.5em; grid-auto-rows: 1.4em; text-align: center; border: 1px #777 solid; background-color: #AAA; padding: 0.5em; }
.confirm > .confirm-message { grid-column: 1 / 3; }
这只是将问题向上移动到调用堆栈,后续函数需要使用await
/async
来确保它们等待用户输入解决:
let a = async function(){
let conf = document.createElement( "DIV" );
conf.className = 'confirm';
let message = document.createElement( "DIV" );
message.className = 'confirm-message';
message.innerText = 'Proceed';
conf.appendChild( message );
let ok = document.createElement( "BUTTON" );
ok.innerText = 'Ok';
conf.appendChild( ok );
let cancel = document.createElement( "BUTTON" );
cancel.innerText = 'Cancel';
conf.appendChild( cancel );
document.body.appendChild( conf );
let v = await new Promise(
response => {
ok .addEventListener( "click", ()=>{ response(true ); }, false );
cancel.addEventListener( "click", ()=>{ response(false); }, false );
}
);
conf.remove();
return v;
};
let b = async function(){ let v = await a(); console.log("b: " + v ); };
let c = async function(){ let v = await b(); console.log( "after b" ); };
(async function(){
let c1 = await c();
let c2 = await c();
})();
.confirm { display: grid; width: min-content; grid-template-columns: 10em 10em; grid-gap: 0.5em; grid-auto-rows: 1.4em; text-align: center; border: 1px #777 solid; background-color: #AAA; padding: 0.5em; }
.confirm > .confirm-message { grid-column: 1 / 3; }
有没有一种方法可以使用新的await
语法来阻止执行,而不改变所有调用函数的签名,并使它们成为async
(以模仿使用内置window.confirm()
function的示例)?
1条答案
按热度按时间yr9zkbsy1#
您应该使用
then()
函数。然后在实现promise后返回async函数的结果。