#typescript #ionic3 #es6-promise #angular-promise
#typescript #ionic3 #es6-обещание #angular-обещание
Вопрос:
Прежде всего хотел бы объяснить, чего я пытаюсь достичь. Я извлекаю рестораны из базы данных, после этого добавляю вычисленное расстояние от позиции пользователя и позиции ресторана. Где я добавляю это как свойство к объекту restaurant. Затем я хотел бы отсортировать свои результаты на основе этого расстояния от ближайшего к удаленному.
Но результат обещания (ресторан с расстоянием) не содержит расстояния.
Вот мой код, как я пробовал, журналы консоли возвращают мне массив С расстоянием, но когда я устанавливаю точку останова в отладчике Chrome, я не могу увидеть это свойство.
Это обещание calculateDistance function
:
calculateDistance(restaurants: Array<Restaurant>): Promise<Array<Restaurant>> {
const promise = new Promise<any>((resolve, reject) => {
// const restaurantDistances = [];
restaurants.map((restaurant) => {
const restaurantLocation: LatLng = new LatLng({
lat: restaurant['Restaurant']['Lat'],
lng: restaurant['Restaurant']['Long']
});
this.locationService.getUserLocation().then(() => {
this.googlemapService.initGoogleMapsApi().then(() => {
const distance = this.googlemapService.computeDistanceBetween(this.locationService.location, restaurantLocation);
restaurant['Restaurant']['Distance'] = distance;
// restaurantDistances.push(restaurant);
console.log(restaurants, 'restMap', restaurant, distance);
resolve(restaurants);
});
}).catch( error => {
console.log('error = ', error);
});
});
});
return promise;
}
это внутри функции успеха:
this.calculateDistance(restaurants).then((restaurantsDist) => {
console.log('after Calc distance', restaurantsDist, restaurants);
this.determinInstanceStorage(fetchMethodName, restaurantsDist, resolve);
});
Кто-нибудь может мне помочь, я разрешаю результат map
методом, возможно, это вызывает проблему?
Ответ №1:
Итак, я думаю, основная проблема, с которой вы сталкиваетесь, заключается в том, что вы вызываете resolve(restaurants)
внутри restaurants.map
цикла. Это означает, что на первой итерации цикла вы собираетесь разрешить обещание. Теперь, если ваш цикл достаточно мал, а время обработки достаточно мало для каждой из итераций, вы можете на самом деле не заметить этого, поскольку цикл будет продолжаться, и данные будут заполнены, но любое исследование «момента времени» (например, точки останова) покажет, что вы видите — что не все рестораны были обработаны.
Есть пара других вещей, которые, я думаю, тоже могли бы помочь. Не будучи знакомым с используемыми вами API или средой, в которой вы работаете, я не могу быть уверен на 100%. С помощью this.locationService.getUserLocation
и this.googleMmapService.initGoogleMapsApi
они выглядят как операции, которые должны выполняться только один раз (не для каждого экземпляра restaurants
цикла). Можете ли вы извлечь их из restaurants.map
цикла?
Кроме того, изменение этого на async
функцию может облегчить чтение, поскольку у вас есть этот многократный каскад then
-х. Итак, в итоге, что-то вроде этого:
async function calculateDistance(restaurants: Array<Restaurant>): Promise<Array<Restaurant>> {
await this.locationService.getUserLocation();
await this.googlemapService.initGoogleMapsApi();
restaurants.map((restaurant) => {
const restaurantLocation: LatLng = new LatLng({
lat: restaurant['Restaurant']['Lat'],
lng: restaurant['Restaurant']['Long']
});
const distance = this.googlemapService.computeDistanceBetween(
this.locationService.location, restaurantLocation
);
restaurant['Restaurant']['Distance'] = distance;
// restaurantDistances.push(restaurant);
console.log(restaurants, 'restMap', restaurant, distance);
});
return restaurants;
}
Это написано «неофициально», поэтому не могу сказать, что оно будет функционировать как есть, но должно дать представление.
Комментарии:
1. Отлично. Дайте мне знать, если поможет.