Как можно вернуть промис без необходимости каждый раз использовать .then?

Я хочу создать функцию, которая будет обрабатывать промисы и возвращать результат, чтобы можно было сразу работать с ним без использования дополнительных функций .then. 

(1) Например, я могу обработать промис следующим образом: 
<pre><code class="javascript">promis.then((value)=&gt; {
div.innerHTML = value[0]; // предположим, это json-объект. 
});</code></pre> 

Однако, как сделать так, чтобы это выглядело так: 
<pre><code class="javascript">function f() {
 promis.then((value)=&gt; {
 return value; // предположим, это json-объект
 });
}
let obj = f();
div.innerHTML = obj[0];</code></pre> 

(2) И второй вопрос: почему в данном примере не требуется использовать .then при передаче значения промиса в качестве аргумента функции? То есть приведенный ниже код работает без дополнительного .then: 
<pre><code class="javascript">async function loadData(url) { 
	let f = await fetch(url);
	
	if (!f.ok) {
		alert('получить файл не удалось');
	} else {
		let json = await f.json(); 
		transferValue(json);  // передаем значение
	}
}

function transferValue(data) {
	div.innerHTML = data[0]; // никаких .then
}</code></pre>
  • 29 октября 2024 г. 13:03
Ответы на вопрос 3
Чтобы корректно работать с промисами без использования `.then` при возврате значений, вам необходимо использовать `async/await`. Ваша функция должна быть асинхронной, и тогда вы сможете просто `return` в этой функции. Вот как можно переписать ваш первый пример:

### 1. Пример использования async/await для возврата промиса:

```javascript
async function f() {
    const value = await promis; // ждем разрешения промиса
    return value; // возвращаем результат
}

async function main() {
    let obj = await f(); // ждем результата функции f
    div.innerHTML = obj[0]; // работаем с результатом
}

// вызываем функцию main, чтобы запустить код
main();
```

Таким образом, вы сможете работать с возвращаемым значением, как с обычным результатом функции.

### 2. Ответ на второй вопрос о передаче значений:

В вашем втором примере вы используете `async/await`, что позволяет вам не использовать `.then`, потому что вы ожидаете (await) разрешение промиса внутри асинхронной функции. Когда функция `loadData` вызывается и достигает `await fetch(url)`, она приостанавливает выполнение на этом этапе до тех пор, пока промис не будет разрешен, а затем продолжает выполнение с результатом. Поэтому, когда вы передаете данные в `transferValue`, это уже значение, которое было получено от промиса.

В итоге, если вы хотите работать с результатами промисов без использования `.then`, применяйте `async/await`, и вы сможете писать более чистый и понятный код.
Ну во-первых, твой await x.json() при await - это тот-же then. 

И тебе правильно сказали, что без await и без костылей - ты eventLoop не обыграешь.

Можно выбрасывать при await и потом ловить то, чем оказывается промис в итоге, можно юзать Promise.withResolvers, что в принципе тоже без await нереально.

Например (с withResolvers):

const { promise, resolve, reject } = Promise.withResolvers()

const getProducts = () => fetch('https://fakestoreapi.com/products')

try {
    resolve(
        (await getProducts()).json()
    )
} catch (e) {
    reject(e)
}

console.log(
    await promise
)


Но тебе выше уже сказали, что такие операции без минимум использования оператора await - нереально исполнить. Не хочешь then - будешь юзать await, не хочешь await - будешь юзать then. Либо создавай своё подобие промисов на костылях, через кастомные события или сигналы.

P.S.: Чтобы понять, почему нельзя сделать то, что хочешь ты - прочитай то что тебе выше написали, а перед/после прочитай это .
Похожие вопросы