Как выйти из цикла for в javascript?

#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 ее в асинхронную функцию.

Затем, всякий раз, когда вы вызываете эту функцию, если вы собираетесь ее ждать, соответствующая функция сайта вызова также должна быть асинхронной. И так далее, и так далее… как вирус или матрешка.