Поскольку обещание представляет собой значение, которое будет доступно в будущем, вы не можете проверить «сейчас» (синхронно), какое из них выполнено успешно.Вместо этого вы должны использовать доступные функции для управления и комбинирования обещаний.Я предполагаю, encryptionTool.decrypt
возвращает PromiseLike<string>
;если это PromiseLike<T>
для какого-то другого T
, просто замените string
на T
в следующем.
Сначала вы можете использовать Promise.resolve
для преобразования PromiseLike<string>
в Promise<string>
.Затем вы хотите использовать Promise.all
, чтобы получить массив обещаний и вернуть обещание массива результатов, чтобы вы могли написать обратный вызов then
для сканирования массива и получения нужного результата.Потенциальная проблема заключается в том, что Promise.all
отклоняет, если любой из предоставленных обещаний отклоняет, и в этом случае вы не видите других результатов.Поэтому, прежде чем использовать Promise.all
, вам необходимо использовать catch
, чтобы сопоставить отклонение со значением дозорного, например null
.Полный код будет выглядеть примерно так (я не проверял его, поэтому возможны ошибки):
// Assuming that encryptionTool.decrypt returns a PromiseLike<string>,
// promises will be a Promise<string | null>[].
let promises = [];
for (let i = 0; i <= locationInputs.length - 1; i++) {
promises.push(
Promise.resolve(encryptionTool.decrypt(locationInputs[i], ciphertext, originalHash))
.catch((error) => null));
}
return Promise.all(promises).then((results) => {
// results is a (string | null)[].
// Look through it, find the non-null result and return it.
});
Обратите внимание, что последний вызов then
генерирует обещание для конечного результата, и высинхронно возвращайте это обещание вызывающей стороне decryptMessage
.
Альтернативный подход - сделать decryptMessage
асинхронной функцией, чтобы вы могли программировать в более привычном стиле.Замените public decryptMessage
на public async decryptMessage
, а затем используйте код, подобный следующему:
for (let i = 0; i <= locationInputs.length - 1; i++) {
try {
return await encryptionTool.decrypt(locationInputs[i], ciphertext, originalHash);
} catch (e) {
// Discard the exception and proceed to the next decryption attempt.
}
}
// TODO: Decide what to return here if all decryptions fail.
Обратите внимание, что таким образом каждое дешифрование не начинается, пока не произойдет сбой предыдущего, поэтому процесс может занять больше времени в зависимости ото том, как реализован веб-крипто-API.