随着ES2017的出现,解决这个问题的答案是async/await。
它是JavaScript中“回调地狱”的解决方案。Promise相当于System.Threading.Tasks.Task。
您可以在异步函数中等待一个Promise。
与C#不同,没有办法在同步函数中调用异步函数。
因此,您只能在异步函数中使用
await等待一个Promise。
async function foo()
{
return 123;
}
let result = await foo();
console.log(result)
您可以使用TypeScript或babel将async/await转译回ES5(当IE11存在时)。
对于IE11,有一个Promise polyfill。
请参见
ECMA-draft 262或
MDN获取更详细的信息。
Promise的一个很好的例子是FETCH API。
fetch-API非常适合用于异步/等待ajax请求。
为什么?因为如果您必须promisify XmlHttpRequest,则会像这样:
<!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" />
<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">
<!--
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 ajaxGet(url, data)
{
var result;
return new Promise(function (resolve, reject)
{
ajax.get(url, data, function (bError, strMessage, iStatus)
{
result = bError;
resolve(result);
}
,true
);
}
);
}
async function main()
{
var ajaxResult = await ajaxGet("./ajax/json.ashx");
console.log("ajaxResult: ", ajaxResult);
}
async function lol()
{
var res = null;
var myPromise = new Promise(function (resolve, reject)
{
var request = new XMLHttpRequest();
request.open('GET', 'https://localhost:57566/ajax/json.ashx');
request.onreadystatechange = function ()
{
console.log("readystate:", request.readyState);
console.log("status:", request.status)
if (request.readyState != 4) return;
if (request.status === 200)
{
console.log("successy")
resolve(request.responseText);
return;
}
if (request.status != 200 && request.status != 0 && request.status != 304)
{
console.log('HTTP error ' + request.status);
reject(new Error("Server error - Status NOK", "filename", "linenum666"));
return;
}
if (request.status === 0)
{
console.log("cancelled:", request)
return;
}
reject(new Error("Strange error", "filename", "linenum666"));
};
request.onerror = function ()
{
console.log("OMG OnError");
reject(new Error("Aww, didn\'t work at all. Network connectivity issue.", "filename", "linenum666"));
};
if (!navigator.onLine)
{
console.log("No internet connection");
reject("No internet connection");
}
else
{
try
{
request.send();
}
catch (ex)
{
console.log("send", ex.message, ex);
}
}
});
return myPromise;
}
async function autorun()
{
console.clear();
try
{
var resp = await lol();
console.log("resp:", resp);
}
catch (ex)
{
console.log("foo", ex.message, ex);
}
console.log("I am here !");
}
if (document.addEventListener) document.addEventListener("DOMContentLoaded", autorun, false);
else if (document.attachEvent) document.attachEvent("onreadystatechange", autorun);
else window.onload = autorun;
</script>
</body>
</html>
postForm()
中尝试使用$.when
。虽然我不确定,但应该可以运行。 - Pranav Singh