如何在同步函数中等待JavaScript中的异步调用?
我最近不得不纠正一个web应用程序(我没有创建)中的安全问题。 安全问题是,它使用的是非http专用cookies。 因此,我必须只设置会话cookie http,这意味着您不能再从javascript读取(和设置)cookie的值。 到目前为止非常容易 更深层次的问题是,使用的是web应用程序如何在同步函数中等待JavaScript中的异步调用?,javascript,ajax,asynchronous,async-await,synchronize,Javascript,Ajax,Asynchronous,Async Await,Synchronize,我最近不得不纠正一个web应用程序(我没有创建)中的安全问题。 安全问题是,它使用的是非http专用cookies。 因此,我必须只设置会话cookie http,这意味着您不能再从javascript读取(和设置)cookie的值。 到目前为止非常容易 更深层次的问题是,使用的是web应用程序 JSON.parse(readCookie(cookieName)).some_value 在一百万个地方 因此,为了不必重写“一百万行代码”,我必须创建一个ajax端点,将http cookie的内
JSON.parse(readCookie(cookieName)).some_value
在一百万个地方
因此,为了不必重写“一百万行代码”,我必须创建一个ajax端点,将http cookie的内容作为JSON并重写
readCookie使用同步ajax请求(而不是读取cookie),因为其余可怕的代码需要
readCookie在这一百万个位置是同步的,因为读取cookie是同步的
现在的问题是,我得到了很多
主线程上的同步XMLHttpRequest已被弃用,因为
它会对最终用户的体验产生不利影响。要获得更多帮助,
检查
这会对调试控制台产生垃圾邮件,更不用说有人决定删除此功能的可能性了
因此,我正在研究新的ES async/await关键字,看看这是否有助于同步发出异步ajax请求(我知道我必须为IE 11使用包装器)
到目前为止,我阅读了这些页面*
但看起来所有新的异步代码似乎只解决了更容易编写异步代码的问题,而没有实现异步代码和现有同步代码之间的互操作。使用我读到的信息,我现在可以像等待同步一样等待异步ajax调用的结果, 但问题是-wait只允许在异步方法中使用。。。 这意味着,即使我可以像等待同步结果一样等待结果,getCookie方法仍然必须是异步的,这使得所有的东西看起来都毫无意义(除非你的整个代码都是异步的,如果你不是从头开始的话,这肯定不是) 我似乎找不到任何关于如何在同步和异步代码之间进行互操作的信息 例如,在C#中,我可以使用.Result从同步上下文调用异步方法,例如
AsyncContext.RunTask(MyAsyncMethod).Result;
或者更容易但不那么安全
MyAsyncMethod(args).Result;
有没有办法在JavaScript中实现同样的效果
当代码库的其余部分是同步的,而没有任何互操作的可能性时,将异步扩展似乎没有什么意义。。。
在2017年的广告中,JavaScript真的没有办法实现这一点吗
我再次强调:我知道如何进行同步ajax调用,我知道如何在回调和/或承诺中使用异步ajax调用。
但我无法弄清楚的是如何同步异步ajax调用(无回调),以便可以从预期同步运行的代码中使用它(在“一百万个位置”) 这就是我迄今为止所尝试的:
(请注意,无论我使用的是
loadQuote
还是main
,文本“Ron once said”仍然首先出现在调试控制台中,如果异步ajax调用已同步解决,则不应出现这种情况。)
标题
身体
{
背景色:#0c70b4;
颜色:#546775;
字体:普通400 18px“PT Sans”,无衬线;
-webkit字体平滑:抗锯齿;
}
函数getQuote(){
var报价;
返回新承诺(功能(解决、拒绝){
get(“./ajax/json.ashx”),null,函数(bError,strMessage,iStatus){
//log(“参数:”,参数);
//日志(“错误:”,bError);
//日志(“消息:”,strMessage);
//控制台日志(“状态:”,iStatus);
quote=bError;
解决(引用)
},对);
/*
请求('./ajax/json.ashx',函数(错误、响应、正文){
引号=正文;
解决(报价);
});
*/
});
}
异步函数main(){
var quote=wait getQuote();
控制台日志(“引号:”,引号);
}
函数myGetQuote(){
var quote=async函数(){return await getQuote();};
控制台日志(“引号:”,引号);
返回报价;
}
函数生成(generatorFunc){
函数连续体(动词,arg){
var结果;
试一试{
结果=生成器[动词](arg);
}捕捉(错误){
退回承诺。拒绝(错误);
}
如果(结果完成){
返回result.value;
}否则{
返回Promise.resolve(result.value)。然后返回(oncompleted,onRejected);
}
}
var生成器=generatorFunc();
var oncompleted=continuer.bind(continuer,“next”);
var onRejected=continuer.bind(continuer,“throw”);
完成时返回();
}
函数loadQuote()
{
返回繁殖(函数*(){
试一试{
let story=yield getQuote();
日志(“故事:”,故事);
//addHtmlToPage(故事标题);
//对于(let chapter of story.chapterURLs.map(getJSON)){addHtmlToPage((yield chapter.html);}addTextToPage(“全部完成”);
}捕捉(错误){
//addTextToPage(“Argh,breaked:+err.message”);
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="google" value="notranslate" />
<!--
<meta name="author" content="name" />
<meta name="description" content="description here" />
<meta name="keywords" content="keywords,here" />
<link rel="shortcut icon" href="favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="stylesheet" href="stylesheet.css" type="text/css" />
-->
<title>Title</title>
<style type="text/css" media="all">
body
{
background-color: #0c70b4;
color: #546775;
font: normal 400 18px "PT Sans", sans-serif;
-webkit-font-smoothing: antialiased;
}
</style>
<script type="text/javascript">
<!--
// http://localhost:57566/foobar/ajax/json.ashx
var ajax = {};
ajax.x = function () {
if (typeof XMLHttpRequest !== 'undefined') {
return new XMLHttpRequest();
}
var versions = [
"MSXML2.XmlHttp.6.0",
"MSXML2.XmlHttp.5.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.2.0",
"Microsoft.XmlHttp"
];
var xhr;
for (var i = 0; i < versions.length; i++) {
try {
xhr = new ActiveXObject(versions[i]);
break;
} catch (e) {
}
}
return xhr;
};
ajax.send = function (url, callback, method, data, async) {
if (async === undefined) {
async = true;
}
var x = ajax.x();
x.open(method, url, async);
x.onreadystatechange = function () {
if (x.readyState == 4) {
callback(x.responseText)
}
};
if (method == 'POST') {
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
x.send(data)
};
ajax.get = function (url, data, callback, async) {
var query = [];
for (var key in data) {
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
ajax.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, async)
};
ajax.post = function (url, data, callback, async) {
var query = [];
for (var key in data) {
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
ajax.send(url, callback, 'POST', query.join('&'), async)
};
///////////
function testAjaxCall() {
ajax.get("./ajax/json.ashx", null, function (bError, strMessage, iStatus)
{
console.log("args:", arguments);
console.log("Error:", bError);
console.log("Message:", strMessage);
console.log("Status:", iStatus);
}
, true
);
}
-->
</script>
</head>
<body>
<script type="text/javascript">
function getQuote() {
var quote;
return new Promise(function (resolve, reject) {
ajax.get("./ajax/json.ashx", null, function (bError, strMessage, iStatus) {
// console.log("args:", arguments);
// console.log("Error:", bError);
// console.log("Message:", strMessage);
// console.log("Status:", iStatus);
quote = bError;
resolve(quote)
}, true);
/*
request('./ajax/json.ashx', function (error, response, body) {
quote = body;
resolve(quote);
});
*/
});
}
async function main() {
var quote = await getQuote();
console.log("quote: ", quote);
}
function myGetQuote() {
var quote = async function () { return await getQuote(); };
console.log("quote: ", quote);
return quote;
}
function spawn(generatorFunc) {
function continuer(verb, arg) {
var result;
try {
result = generator[verb](arg);
} catch (err) {
return Promise.reject(err);
}
if (result.done) {
return result.value;
} else {
return Promise.resolve(result.value).then(onFulfilled, onRejected);
}
}
var generator = generatorFunc();
var onFulfilled = continuer.bind(continuer, "next");
var onRejected = continuer.bind(continuer, "throw");
return onFulfilled();
}
function loadQuote()
{
return spawn(function *() {
try {
let story = yield getQuote();
console.log("story:", story);
// addHtmlToPage(story.heading);
// for (let chapter of story.chapterURLs.map(getJSON)) { addHtmlToPage((yield chapter).html); } addTextToPage("All done");
} catch (err) {
//addTextToPage("Argh, broken: " + err.message);
console.log("Argh, broken: " + err.message);
}
//document.querySelector('.spinner').style.display = 'none';
});
}
function autorun()
{
console.clear();
// main();
// main();
loadQuote();
//var quote = myGetQuote();
// console.log("quote: ", quote);
console.log('Ron once said,');
}
if (document.addEventListener) document.addEventListener("DOMContentLoaded", autorun, false);
else if (document.attachEvent) document.attachEvent("onreadystatechange", autorun);
else window.onload = autorun;
</script>
</body>
</html>
async function asyncExample () {
try {
const response = await myPromise()
// the code here will wait for the
// promise to fullfil
} catch (error) {
// the code here will execute if the promise fails
}
}
function nonAsyncExample () {
asyncExample ()
console.log('this will not wait for the async to finish')
// as it's not wrapped in an async function itself
}
function init () {
// perform initialisations here
}
document.addEventListener("DOMContentLoaded", init)
document.addEventListener("DOMContentLoaded", function () {
getAjaxConfig().then(function (response) {
window.cookieStash = response
init()
}
})