#javascript #for-loop
Вопрос:
Я знаю, что этот вопрос задавался много раз, но, как ни странно, ответы в других сообщениях не решили мою проблему:
handleFile(files) {
var f = files[0]
var dataSet = JSZip.loadAsync(f).then(function (zip) {
for (var filename in zip.files) {
const one_dicom_file = zip.files[filename]
console.log('--------- one_dicom_file ----------', one_dicom_file)
try {
one_dicom_file.async("arraybuffer").then(function (ArrayBuffer) {
var byteArray = new Uint8Array(ArrayBuffer);
var dataSet = dicomParser.parseDicom(byteArray);
console.log(filename, 'parsed dataSet: ', dataSet);
return dataSet
// EDIT: OP is Missing close curly bracket here!!
} catch (error) {
console.error(error);
}
console.log('check 1')
}
}, function (e) {
console.log(e)
});
}
Я перебираю содержимое zip-файла, и когда обнаруживается первый dicom
файл (формат для медицинского изображения), я анализирую его с помощью вызова библиотеки dicomParser.parseDicom()
.
После успешного выполнения этой функции я хочу немедленно завершить итерацию. Другие файлы dicom можно игнорировать в целях повышения производительности.
Однако приведенный выше код будет напечатан console.log(filename, 'parsed dataSet: ', dataSet);
для каждого отдельного файла dicom. Линия return dataSet
вообще ничего не делает с for
петлей. Кроме того, check 1
печатается для каждого файла dicom.
Я также попытался заменить return dataSet
на break
, в этом случае Unsyntactic break
будет выдана ошибка.
Другие ответы утверждали, что оба return
и break
должны остановить цикл for, но они этого не делают.
Я очень новичок в javascript, так что извините, если это глупый вопрос. Я привык к python, а синтаксис javascript слишком сложен…
Комментарии:
1. у вас нет ни перерыва, ни возврата в цикле for … возврат НЕ находится в цикле for, он находится в функции, вызываемой внутри цикла for, поэтому ничего не делает с циклом for — ваш отступ скрывает этот факт
2. честно говоря, код, который вы опубликовали, в любом случае синтаксически неверен —
try
он находится вне.then(function(ArrayBuffer){
обратного вызова, аcatch
внутри него — пожалуйста, опубликуйте синтаксически правильный код3. Я отредактировал отступ, чтобы было ясно, что в OP отсутствует закрывающая скобка
4. ах, какая я глупая….
5. Вы должны использовать
async
/await
вместо.then()
того, чтобы иметь возможность выйти из цикла (и в первую очередь выполнять итерацию последовательно)
Ответ №1:
Функция обратного вызова, которую вы передаете, .then(function (ArrayBuffer) { }
будет выполняться асинхронно.
Это означает, что ваша программа продолжит поток, а не будет ждать его выполнения и результата. Из-за этого вы не можете использовать результат этой функции в качестве условия для выхода из цикла. Программа перейдет к следующему циклу независимо от того, что произошло внутри этой функции.
Чтобы принять решение о разрыве цикла или нет на основе результата функции, вы должны заблокировать поток программы до тех пор, пока функция не будет завершена.
Я предлагаю вам взглянуть на await
ключевое слово и функциональность. В Интернете есть множество учебных пособий по этому вопросу, например, здесь или здесь.
Я не знаю подробностей функций, которые вы вызываете, но это может выглядеть примерно так:
async function handleFile(files) {
var f = files[0]
var zip = await JSZip.loadAsync(f)
for (var filename in zip.files) {
const one_dicom_file = zip.files[filename]
console.log('--------- one_dicom_file ----------', one_dicom_file)
try {
var arrayBuffer = await one_dicom_file.async("arraybuffer")
var byteArray = new Uint8Array(arrayBuffer)
var dataSet = dicomParser.parseDicom(byteArray)
console.log(filename, 'parsed dataSet: ', dataSet)
return dataSet
} catch (error) {
console.error(error)
}
}
}
Просто имейте в виду , что вы можете только await
внутри функции, которая есть async
, поэтому вам нужно преобразовать handleFile
ее в асинхронную функцию.
Затем, всякий раз, когда вы вызываете эту функцию, если вы собираетесь ее ждать, соответствующая функция сайта вызова также должна быть асинхронной. И так далее, и так далее… как вирус или матрешка.