Вопрос был:
Как вернуть ответ от асинхронного вызова?
, который может быть интерпретирован как:
Как сделать синхронный асинхронный код синхронным?
Решение будет состоять в том, чтобы избежать обратных вызовов и использовать комбинацию Promises и async / await.
Я хотел бы привести пример для запроса Ajax.
(Хотя он может быть записан в Javascript, я предпочитаю писать его на Python и компилировать его в Javascript, используя Transcrypt . Это будет достаточно ясно.)
Позволяет сначала включить использование JQuery, чтобы
$
был доступен какS
:__pragma__ ('alias', 'S', '$')
Определить функцию, которая возвращает Promise, в этом случае вызов Ajax:
def read(url: str): deferred = S.Deferred() S.ajax({'type': "POST", 'url': url, 'data': { }, 'success': lambda d: deferred.resolve(d), 'error': lambda e: deferred.reject(e) }) return deferred.promise()
Использовать асинхронный код, как если бы он был синхронным:
async def readALot(): try: result1 = await read("url_1") result2 = await read("url_2") except Exception: console.warn("Reading a lot failed")
Вам нужно использовать функцию сравнения, это функции, которые из двух экземпляров вашего типа возвращают целое число, возвращающее 0, если оба равны, отрицательное значение, если первое меньше второго и положительное значение, если первый больше, чем второй.
MSDN имеет nice table , который легче отслеживать, чем текст (StackOverflow по-прежнему не поддерживает таблицы в 2014 году)
IComparer<T>
Большинство методов сортировки принимают пользовательскую реализацию сопоставления типа IComparer<T>
, вы должны создать один инкапсулирующий ваши пользовательские правила для Group
:
class GroupComparer : IComparer<Group>
{
public int Compare(Group a, Group b)
{
if (a != null && b != null && (a.Id == 0 || b.Id == 0))
{
if (a.Id == b.Id)
{
// Mandatory as some sort algorithms require Compare(a, b) and Compare(b, a) to be consitent
return 0;
}
return a.Id == 0 ? -1 : 1;
}
if (a == null || b == null)
{
if (ReferenceEquals(a, b))
{
return 0;
}
return a == null ? -1 : 1;
}
return Comparer<string>.Default.Compare(a.Name, b.Name);
}
}
Использование:
items.OrderBy(_ => _, new GroupAuthorityComparer());
IComparable<T>
Если это единственный способ сравнить экземпляры Group
, вы должны сделать его реализацией IComparable<T>
, чтобы дополнительный код не требовался, если кто-то хочет сортировать ваш класс:
class Group : IComparable<Group>
{
...
public int CompareTo(Group b)
{
if (b != null && (Id == 0 || b.Id == 0))
{
if (Id == b.Id)
{
// Mandatory as some sort algorithms require Compare(a, b) and Compare(b, a) to be consitent
return 0;
}
return Id == 0 ? -1 : 1;
}
return Comparer<string>.Default.Compare(Name, b.Name);
}
}
Использование:
items.OrderBy(_ => _.Group);
Выбор между одним путь или другое должно выполняться в зависимости от того, где используется этот конкретный компаратор: является ли это основным заказом для этого типа товара или просто для заказа который должен использоваться в одном конкретном случае, например, только в каком-то административном представлении.
Вы даже можете подняться на один уровень и обеспечить реализацию IComparable<GroupAuthority>
(это легко после реализации группы IComparable<Group>
):
class GroupAuthority : IComparable<GroupAuthority>
{
...
public int CompareTo(GroupAuthority b)
{
return Comparer<Group>.Default.Compare(Group, b.Group);
}
}
Использование:
items.OrderBy(_ => _);
Преимущество последнего состоит в том, что он будет использоваться автоматически, поэтому код типа: GroupAuthoritys.ToList().Sort()
сделает правильную вещь из коробка.
public IEnumerable<GroupAuthority> GroupAuthoritysSorted
{
get
{
return GroupAuthoritys.OrderBy(x => x.Group.ID == 0)
.ThenBy(x => x.Group.Name);
}
}
Вы можете попробовать что-то вроде этого
list.Sort((x, y) =>
{
if (x.Id == 0)
{
return -1;
}
if (y.Id == 0)
{
return 1;
}
return x.Group.Name.CompareTo(y.Group.Name);
});
Где список List<T>
.
Этот метод использует опцию пользовательской сортировки, предоставленную List<T>
, используя Comparison<T>
делегат.
В основном, что делает этот метод, он просто добавляет особое условие для сравнения, когда Id
. Если он равен нулю, он вернет значение, указывающее, что объект меньше, что заставляет объект входить в верхнюю часть списка. Если нет, он сортирует объект, используя его свойство Group.Name
в порядке возрастания.