Задать вопрос
@Bezlepkin
Yii, PHP, JS, Android

Как побороть ассинхронность при Ajax?

Привет! Запарился с проблемой.

Есть код который в аяксе забирает юзеров и строит массив.

users (ids) {
  return new Promise((resolve, reject) => {
    let users = {dd: 'ff'}
      for (let i = 0; i < ids.length; i++) {
        userApi.findOne(ids[i]).then((user) => {
	  users[user.id] = user
        })
      }
      resolve(users)
    })
}


users(userIds).then((users) => {
  window.localStorage.removeItem('users')
  window.localStorage.setItem('users',  JSON.stringify(users))
  })
})


Возвращается объект {dd: 'ff'}
Как в таких случаях быть?
  • Вопрос задан
  • 84 просмотра
Подписаться 1 Средний 1 комментарий
Решения вопроса 1
shmatuan
@shmatuan
8 year of Web, 5 years of Vue
1. userApi.findById(ids[i]).then((err, user) => {})

2. Использовать async/await или
users (ids) {
  return new Promise((resolve, reject) => {
    let users = {dd: 'ff'}
    let icount = 0;
      for (let i = 0; i < ids.length; i++) {
        userApi.findById(ids[i]).then((err, user) => {
          users[user.id] = user
          icount ++;
          if(icount  === ids.length - 1) {
            resolve(users)
           }
        })
      }      
    })
}


3. Прочитать более внимательно про асинхронность в js:
for (let i = 0; i < ids.length; i++) {
        userApi.findOne(ids[i]).then((user) => {  // выполняется запрос в БД ids.length - 1 раз ОДНОВРЕМЕННО (т.к. асинхронность и не нужно ждать)
           users[user.id] = user // только тут что-то возвращается ЧЕРЕЗ ВРЕМЯ из БД
           // p.s. только т.к. нужны аргументы (err, user), то в users[user.id] = user на самом деле записывается переменная error, а не user
        }) 
      } //  выходит из цикла, т.к. все запросы он отправил (НО не получил ещё ответы)
      resolve(users) // сразу после выполнения цикла отправляет users (но ответ даже на первый запрос ещё не пришёл)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы