Мне трудно заставить мой код работать в правильной последовательности. Мне действительно нужно понять, как правильно использовать обещания. Я прочитал вопрос «Как вернуть ответ от асинхронного вызова?»:
Как вернуть ответ от асинхронного вызова?
Все ответы вращаются вокруг запросов XHR и подобных. Я использую класс Image () в Javascript, чтобы получить разрешение из файлов JPEG. Это функция, которая выбирает массив файлов с моего сервера, а затем для каждого добавляет в массив идентификатор и разрешение. Единственное, что мне нужно для Image () - это вернуть ширину и высоту, но мне нужен мой код, чтобы дождаться его завершения до 1057 *, прежде чем двигаться дальше.
У меня тоже есть эта проблема в других местах и мой проект становится нестабильным. Я думаю, это потому, что все происходит не в правильной последовательности.
Я действительно изо всех сил пытаюсь понять, как реструктурировать мой код так, чтобы он ожидал, пока объект Image () прочитает из файла и вернет свое разрешение, прежде чем он выключится и использует упомянутую информацию (которой там нет). ).
Полагаю, причина, по которой этот вопрос отличается от упомянутого выше, заключается в том, что мне не нужно выполнять никаких операций с данными в обещании, кроме их извлечения. Если бы это был запрос XHR, я мог бы ответить. Отправить его, а если бы это был массив, я бы мог Array.filter, но это не так, и мне просто нужно его вернуть.
Вот мой код: getJpegs возвращает массив файлов с сервера.
export const getJpegs = async () => {
return await fetch(apiUrl + 'getjpegs')
.then( async response => {
if (response.ok) return await response.json()
else return await response.text()
})
.then( async responseData => {
let newJpegs = await responseData.map( **async** (file, i) => {
const img = **await** new Image()
img.src = imageUrl + file
return {
file: file,
id: i,
res: {
width: img.width,
height: img.height
}
}
})
return newJpegs;
})
.catch(err => console.log('ERROR!!!', err))
}
Если я удаляю асин c и ожидаю, что теги, которые я выделил, работает, за исключением случаев, когда сначала вы загружаете страницу, значения ширины и высоты не определены, пока вы не обновите ее sh. С их помощью значения ширины и высоты определяются как выполненное обещание, а не значения, которые мне нужны!
Как мне go изменить структуру этого кода для достижения того, чего я хочу?
Спасибо.
...
Хорошо, я тоже попробовал:
export const getJpegs = async () => {
return await fetch(apiUrl + 'getjpegs')
.then( async response => {
if (response.ok) return await response.json()
else return await response.text()
})
.then( async responseData => {
let newJpegs = await responseData.map( (file, i) => {
let dimensions = {};
const img = new Image()
img.onload( () => {
dimensions = {
width: img.width,
height: img.height
}
})
img.src = imageUrl + file
return {
file: file,
id: i,
res: dimensions
}
})
return newJpegs;
})
.catch(err => console.log('ERROR!!!', err))
}
Как мне заставить его ждать?
ОБНОВЛЕНИЕ
Спасибо @Supercool, этот вопрос, безусловно, очень похож на мой. Разница лишь в том, что я использую объект Image () вместо второго обещания fetch ().
Я пробовал это:
export const getJpegs = async () => {
return await fetch(apiUrl + 'getjpegs')
.then( async response => {
if (response.ok) return await response.json()
else return await response.text()
})
.then( async responseData => {
let newJpegs = [];
await Promise.all(responseData.map( async (file, i) => {
const img = await new Image()
await img.addEventListener('load', () => {
newJpegs.push({
file: file,
id: i,
res: { width: img.width, height: img.height }
})
})
img.src = "./images/resize300/" + file
}))
console.log(newJpegs)
return newJpegs;
})
Он все еще не ожидает должным образом, хотя в конце файла console.log он выводит массив со всеми правильными данными, но с остальными программа просто продолжает, как если бы массив был пустым. Я предполагаю, что это обновляет память после того, как она проходит через остальную часть программы!
Если я вместо этого console.log (JSON .stringify (newJpegs)) вы просто увидите пустой массив ("[]"), чтобы подтвердить, что он все еще не ждет !!
Будут с благодарностью приняты любые другие предложения,
Спасибо.
ОБНОВЛЕНИЕ
Хорошо, я решил проблему для всех, кто заинтересован. Проблема заключалась в том, что и метод Array.map (), и функция обратного вызова, которую он возвращает (с экземпляром Image () в), должны быть заключены в обещание. Вот рабочий код:
export const getJpegs = async () => {
return await fetch(apiUrl + 'getjpegs')
.then( async response => {
if (response.ok) return await response.json()
else return await response.text()
})
.then( async responseData => {
let newJpegs = [];
await Promise.all(responseData.map( (file, i) => {
return new Promise((resolve, reject) => {
const img = new Image()
img.addEventListener('load', () => {
resolve({
file: file,
id: i,
res: { width: img.width, height: img.height }
})
})
img.src = "./images/resize300/" + file
}).then( response => newJpegs.push(response) )
}))
console.log(newJpegs)
return newJpegs;
})
.catch(err => console.log('ERROR!!!', err))
}
Спасибо за вашу помощь.