2015-07-24 2 views
0

Я должен получить description в переменной tmp, и я не знаю, как синхронизировать этот код, может кто-нибудь мне помочь?Как я могу синхронизировать код обратного вызова?

Мы хотим отобразить имя пользователя контакта first_name в календаре, то есть прикрепить заголовок к user.first_name. Таким образом, мы захватываем все события с сервера, однако для каждого события есть заказы и заказы, содержащие идентификатор пользователя, чтобы захватывать пользовательские данные от contact_users. Затем нам нужно построить объект и нажать его в массив, который имеет все события, а именно tmp. callback вызывается в конце для отображения событий в календаре.

Event.query({ 
    businessId: $stateParams.businessId 
}) 
.$promise.then(function(events) { 
    events.forEach(function(event) { 
    var tmpData = {}; 
    var description = ''; 
    $http.get('/businesses/'+event.business_id+'/events/'+event.id+'/bookings') 
    .then(function(bookings) { 
     if(bookings.data) { 
     $http.get('/businesses/'+event.business_id+'/contact_users/'+bookings.data[0].people_id) 
     .then(function(user) { 
      description = user.data.first_name; 
     }); 
     } 
    }); 
    tmpData = { 
     eventId: event.id, 
     title: description, 
     start: event.starts_at, 
     end: event.ends_at, 
     business_id: event.business_id, 
     employment_id: event.employment_id, 
     professional_id: event.professional_id, 
     service_id: event.service_id, 
    }; 
    tmp.push(tmpData); 
    }); 
    return tmp; 
}).then(function(result) { 
    callback(tmp); 
}); 

Обратный вызов связан с fullcalendar callback события обжигали в методе events.

+0

Вы просто не можете сделать асинхронную операцию внезапно синхронной. В Javascript это невозможно. Похоже, вы пытаетесь использовать обещания, что хорошо. Но выполнение является ошибочным. У вас, по-видимому, есть несколько «событий», которые вы пытаетесь выполнить. Если вы можете описать словами, что вы пытаетесь выполнить с этими событиями (используйте ссылку для редактирования, чтобы изменить свой вопрос), то мы, вероятно, сможем помочь вам исправить этот код. Но, пожалуйста, опишите желаемый результат словами. Когда вы редактируете вопрос, напишите мне комментарий, и я посмотрю. – jfriend00

+0

Я сделал изменения, вы можете это понять? Я могу описать больше, очень ценю вашу помощь[email protected] jfriend00 –

ответ

3

Есть два ключевых понятия при работе с Promise обратных вызовами:

Возвращением значения от успеха обратного вызова Promise вызывает вызывают следующее обещание быть решены с этим значением.

$q.when().then(function() { 
    return 3; 
}).then(function (result) { 
    // result === 3 
}); 

Возвращение другой Promise от успеха обратного вызова Promise эффективно заменяет существующее обещание.

$q.when().then(function() { 
    return $timeout(function() { return 3 }, 1000); 
}).then(function (result) { 
    // called 1000ms later 
    // result === 3 
}); 

Кроме того, есть конструкция $q.all(promises) которая принимает массив обещаний, и возвращает новое обещание, что не будет решена, когда promises все решены (или когда один из них отвергается).


У меня нет доступа к серверной, так что я не мог проверить это, но что-то, как это должно работать для вас:

Event.query({ businessId: $stateParams.businessId }).$promise 
    .then(function (events) { 
    // get array of $HttpPromise objects 
    var promises = events.map(function (event) { 
     return $http.get('/businesses/' + event.business_id + '/events/' + event.id + '/bookings') 
     .then(function (response) { 
      var bookings = response.data; 

      // "transformed" event object 
      var evt = { 
      eventId: event.id, 
      title: '', 
      start: event.starts_at, 
      end: event.ends_at, 
      business_id: event.business_id, 
      employment_id: event.employment_id, 
      professional_id: event.professional_id, 
      service_id: event.service_id 
      }; 

      // each promised is replaced either with a new $HttpPromise... 
      if (bookings) { 
      return $http.get('/businesses/' + event.business_id + '/contact_users/' + bookings[0].people_id) 
       .then(function (response) { 
       var user = response.data; 

       evt.title = user.first_name; 
       return evt; 
       }); 
      } 

      // ...or with an immediately resolved event 
      return evt; 
     }) 
    }); 

    // wait for all promises to be resolved 
    return $q.all(promises); 
    }).then(function (results) { 
    // results is an array of transformed events 
    callback(results); 
    }); 

примечание стороны: другой вариант не дожидаться того, что внутренний $http обещал решить, и просто вернуть «неполный» объект evt.

// launch a promise which updates evt when resolved 
if (bookings) { 
    $http.get('/businesses/' + event.business_id + '/contact_users/' + bookings[0].people_id) 
     .then(function (response) { 
      var user = response.data; 

      // update evt reference 
      evt.title = user.first_name; 
     }); 
} 

// immediately resolve with "incomplete" evt 
return evt; 

Угловой триггер является дайджестом каждый раз, когда обещание разрешается. В зависимости от того, как вы настроите свои шаблоны/рендеринг, это может привести к тому, что сначала будут показаны все события с пустым title, а затем повторно рендеринг с first_name с, когда они станут доступными. Обратите внимание, что это требует, чтобы вы поддерживали evt ссылки повсюду между вашим обратным вызовом и вашими шаблонами.

+0

красиво описано – charlietfl

+0

Это работает очень хорошо, за исключением того, что 'title' по какой-то причине не определено. –

+0

Является ли 'title' undefined или пустой строкой? Вы можете отлаживать обратный вызов для внутреннего '$ http' обещания? Что содержится в переменной 'user'? –

Смежные вопросы