我具有以下两个功能:
function scan_request(address, file_url) {
$.ajax({
type: "POST",
async: true,
crossDomain: true,
url: 'http://some_site/api/file/scan',
dataType: "text",
success: function (data, textStatus, jqXHR) {
var json = $.parseJSON(data);//get json response and parse it
$(json).each(function (i, val) {//extract data from json
$.each(val, async function (key, value) {
if (key.toLowerCase() == "jobid") {
var result = await query_request();
alert("result:" + result);
}
});
});
}
});
}
async function query_request() {
var settings = {
"async": true,
"crossDomain": true,
"url": 'http://some_site/api/file/query',
"method": "POST"
}
var res;
$.ajax(settings).then(function (response) {
alert("response: " + response);
res = response;
});
return res;
}
它首先提醒result: undefined
及其发出警报后:response: [object Object]
但是我期望:
第一警报response: [object Object]
并且在警报result: [object Object]
似乎没有等待呼叫:var result = await query_request();
,因此结果是不确定的,并且警报出现在内部警报之前,我想念什么?
答案 0 :(得分:1)
您只能await
个承诺。 (或返回承诺的函数。)
您的query_request()
应该返回由$.ajax()
创建的诺言。而且,由于它不需要等待任何自身,因此不需要将其标记为async
。
// returns a promise, i.e. can be awaited in caller
function query_request(value) {
return $.ajax({
crossDomain: true,
url: 'http://some_site/api/file/query',
method: "POST",
data: {jobid: value}
});
}
现在,您可以在await
函数中query_request()
的结果async
:
$(json).each(function (i, val) {
$.each(val, async function (key, value) {
if (key.toLowerCase() == "jobid") {
var result = await query_request(value);
alert("result:" + result);
}
});
});
但是,此代码有一个问题-当所有请求实际上都可以并行运行时,它会在循环内将请求进行菊花链式链接。这意味着它比需要的要慢。
稍微改变一下方法,我们可以确保Ajax请求是并行运行的,而不是一个接一个地运行:
async function (data, textStatus, jqXHR) {
var todo = [], pending, results;
// make a list of all the things we want to request
$(json).each(async function (i, val) {
$.each(val, function (key, value) {
if (key.toLowerCase() == "jobid") todo.push(value);
});
});
// request them all in parallel (=> array of promises)
pending = todo.map(query_request);
// wait for all of the results
results = await Promise.all(pending)
// ...now work with the results
}