@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
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 (но ответ даже на первый запрос ещё не пришёл)
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы