我在.Net Core Framework中编写Web应用程序,并且前端的某些元素使用Ajax调用返回特定数据的API。
如果我在一个需要1个API调用的页面上,它工作正常,但是当我进入一个调用多个调用的页面时,调试(好吧,在代码中逐行)调试器在代码中上下跳动变得很糟糕,最后结果都会以错误结束。
如果一个网站拨打更多电话,我很少能得到结果,有时它会发生,但可能性是...... 1/50,这是不可接受的。
奇怪的是,在我访问这样的页面然后返回到进行1次呼叫的页面时,即使该1次呼叫以错误结束。
我不确定我需要在这里包含什么作为代码,所以我将添加jquery和动作。
在此处输入任何代码之前,我想解释一下我的问题.. 我想知道究竟是什么造成了这种情况,为什么ajax调用导致Action的并行执行?我怎么能强制ajax调用逐个运行或者做任何其他事情来解决这个问题。我相信一些观点最多应该拨打30,40个电话,如果有2个电话会引起这样的问题,那么这里显然存在一个问题,但不幸的是我还没有足够的技能来查看和修复它。 / p>
非常感谢任何帮助。
jquery(我已经删除了一些代码,因为它们并不相关。它只是一些类更改):
$(window).ready(function () {
$('.price').each(function (i, e) {
var id = $(e).data('skinid');
var exterior = $(e).data('exterior');
var type = $(e).data('type');
$.ajax({
type: "GET",
url: "/Skin/GetPrice",
data: { Id: id, Exterior : exterior, Type : type },
cache: false,
dataType: "json",
}).complete(function (data) {
var price = data.responseJSON.price;
if (data.responseJSON.querySuccessful)
{
if (data.responseJSON.listingExists)
{
//do stuff here
}
else
{
//other stuff here
}
}
else
{
//print error..
}
});
});
});
行动很长,所以我也将其缩短:
[HttpGet]
public async Task<ActionResult> GetPrice(int Id = 0, string Exterior = null, string Type = null)
{
PriceViewModel model = null;
if (_context.Skins.Any(x => x.Id == Id))
{
if (Type == "Skin")
{
Skin Query = _context.Skins.Where(x => x.Id == Id).Include(x => x.Weapon).Include(x => x.Quality).Select(x => x).Single();
using (var client = new HttpClient())
{
try
{
string uri = "/market/priceoverview/?currency=3&appid=730&market_hash_name=" + Query.Weapon.Name.Replace(" ", "%20") + "%20|%20" + Query.Name.Replace(" ", "%20") + "%20(" + Exterior.Replace(" ", "%20") + ")";
client.BaseAddress = new Uri("http://steamcommunity.com");
var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode(); // Throw in not success
var stringResponse = await response.Content.ReadAsStringAsync();
JObject data = JObject.Parse(stringResponse);
if (data["success"].Value<bool>())
{
if (data["lowest_price"] != null)
{
// return good model
}
//return no result model
}
}
catch
{
// return error
}
}
}
if (Type == "Skin-List")
{
Skin Query = _context.Skins.Where(x => x.Id == Id).Include(x => x.Weapon).Include(x => x.Quality).Select(x => x).Single();
Dictionary<Exterior, PriceViewModel> PossibleExteriors = new Dictionary<Exterior, PriceViewModel>();
bool possible = false;
foreach (Exterior e in _context.Exteriors)
{
if (e.Name == Query.BestExterior)
possible = true;
if (possible)
PossibleExteriors.Add(e, null);
if (e.Name == Query.WorstExterior)
possible = false;
}
List<Exterior> exteriors = PossibleExteriors.Keys.ToList();
foreach (Exterior e in exteriors)
{
using (var client = new HttpClient())
{
try
{
client.BaseAddress = new Uri("http://steamcommunity.com");
string uri = "/market/priceoverview/?currency=3&appid=730&market_hash_name=" + Query.Weapon.Name.Replace(" ", "%20") + "%20|%20" + Query.Name.Replace(" ", "%20") + "%20(" + e.Name.Replace(" ", "%20") + ")";
var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode(); // Throw in not success
var stringResponse = await response.Content.ReadAsStringAsync();
JObject data = JObject.Parse(stringResponse);
if (data["success"].Value<bool>())
{
if (data["lowest_price"] != null)
{
model = new PriceViewModel
{
QuerySuccessful = true,
ListingExists = true,
ListingUrl = "http://steamcommunity.com/market/listings/730/" + Query.Weapon.Name + " | " + Query.Name + " (" + e.Name.Replace(" ", "%20") + ")",
Price = data["lowest_price"].ToString()
};
PossibleExteriors[e] = model;
}
else
{
model = new PriceViewModel
{
QuerySuccessful = true,
ListingExists = false,
ListingUrl = "http://steamcommunity.com/market/listings/730/" + Query.Weapon.Name + " | " + Query.Name + " (" + e.Name.Replace(" ", "%20") + ")",
Price = ""
};
PossibleExteriors[e] = model;
}
}
}
catch
{
model = new PriceViewModel
{
QuerySuccessful = false,
ListingExists = false,
Price = ""
};
PossibleExteriors[e] = null;
}
}
}
if (PossibleExteriors.Values.Any(x => x != null))
{
//return good model
}
else
{
//return empty
}
}
}
//return error
}
答案 0 :(得分:0)
我想知道究竟是什么造成了这种情况,为什么ajax调用导致Action的并行执行?我怎么能强制ajax调用逐个运行或者做任何其他事情来解决这个问题。< / p>
你对异步调用有一个基本的误解。此JavaScript将触发请求,然后在获得响应之前继续进入循环的下一次迭代。每当异步调用完成时,无论何时发生以及发生的顺序,都将调用complete
函数。这意味着新调用的到达速度快于应用程序返回结果的速度,因此它的工作不止一个一次请求。完全正常!
如果需要按特定顺序进行这些调用,为什么不将它们全部归为一个请求?将项列表传递到data
属性并在C#中循环。
如果这必须是JavaScript中的循环,则需要等待来自异步调用的响应(基本上使其同步)如果要同步执行此调用,如调用GetPrice
,获得响应,对响应做一些事情,然后进行下一次迭代并重复,你需要改变方法。
var $prices = $('.prices').map(function() {
return new { Id: id, Exterior : exterior, Type : type }
});
getPrice($prices, 0);
function getPrice(prices, index) {
$.ajax({
type: "GET",
url: "/Skin/GetPrice",
data: prices[index] // if this were the whole prices list, you could do the loop in C# instead
cache: false,
dataType: "json",
}).complete(function (data) {
// do all that processing stuff
index++;
// if there are more prices to compute, call the function again
if (prices.length - 1 >= index) {
getPrice(prices, index);
}
});
}