Как следует из названия, ключевое слово await
заставит функцию «ждать», пока ее обещание не разрешится, перед выполнением следующей строки. Весь смысл await
в том, чтобы заставить код дождаться завершения операции перед продолжением.
Разница между этим и блокирующим кодом состоит в том, что мир вне функции может продолжать выполнение, пока функция ожидает завершения асинхронных операций.
async
и await
- это просто синтаксический сахар поверх обещаний. Они позволяют писать код, очень похожий на обычный синхронный код, даже если он использует скрытые обещания. Если мы переведем ваш пример на что-то, что явно работает с обещаниями, это будет выглядеть примерно так:
function myAsyncFunction() {
return myAPICall('https://jsonplaceholder.typicode.com/posts/1')
.then(function (data) {
let result = 2 + 2;
return data;
})
.catch(function (ex) {
return ex;
});
}
Как мы видим здесь, строка let result = 2 + 2;
находится внутри обработчика .then()
, что означает, что она не будет выполняться, пока myAPICall()
не будет разрешен. То же самое и с await
. await
просто абстрагирует .then()
для вас.
Следует иметь в виду (и я думаю, что то, что вы ищете), что вам не нужно сразу использовать await
. Если бы вы написали свою функцию вот так, то вы могли бы сразу выполнить строку let result = 2 + 2;
:
const timeout =
seconds => new Promise(res => setTimeout(res, seconds * 1000));
function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}
async function myAsyncFunction() {
try {
console.log('starting');
// just starting the API call and storing the promise for now. not waiting yet
let dataP = myAPICall('https://jsonplaceholder.typicode.com/posts/1');
let result = 2 + 2;
// Executes right away
console.log('result', result);
// wait now
let data = await dataP;
// Executes after one second
console.log('data', data);
return data;
} catch (ex) {
return ex;
}
}
myAsyncFunction();
После некоторого разъяснения я вижу, что вы действительно хотели знать, как избежать необходимости ждать двух асинхронных операций одну за другой и вместо этого заставить их выполняться параллельно. В самом деле, если вы используете один await
за другим, второй не начнет выполняться, пока не завершится первый:
const timeout =
seconds => new Promise(res => setTimeout(res, seconds * 1000));
function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}
async function myAsyncFunction() {
try {
console.log('starting');
let data1 = await myAPICall('https://jsonplaceholder.typicode.com/posts/1');
// logs after one second
console.log('data1', data1);
let data2 = await myAPICall('https://jsonplaceholder.typicode.com/posts/2');
// logs after one more second
console.log('data2', data2);
} catch (ex) {
return ex;
}
}
myAsyncFunction();
Чтобы избежать этого, вы можете запустить обе асинхронные операции, выполнив их, не ожидая их, назначив их обещания некоторым переменным. Тогда вы можете дождаться обоих обещаний:
const timeout =
seconds => new Promise(res => setTimeout(res, seconds * 1000));
function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}
async function myAsyncFunction() {
try {
console.log('starting');
// both lines execute right away
let dataP1 = myAPICall('https://jsonplaceholder.typicode.com/posts/1');
let dataP2 = myAPICall('https://jsonplaceholder.typicode.com/posts/2');
let data1 = await dataP1;
let data2 = await dataP2;
// logs after one second
console.log('data1', data1);
console.log('data2', data2);
} catch (ex) {
return ex;
}
}
myAsyncFunction();
Один из альтернативных способов сделать это - использовать Promise.all()
с некоторой декомпозицией массива:
const timeout =
seconds => new Promise(res => setTimeout(res, seconds * 1000));
function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}
async function myAsyncFunction() {
try {
console.log('starting');
// both myAPICall invocations execute right away
const [data1, data2] = await Promise.all([
myAPICall('https://jsonplaceholder.typicode.com/posts/1'),
myAPICall('https://jsonplaceholder.typicode.com/posts/2'),
]);
// logs after one second
console.log('data1', data1);
console.log('data2', data2);
} catch (ex) {
return ex;
}
}
myAsyncFunction();
person
JLRishe
schedule
09.04.2017
.then()
. И вся ваша функция является асинхронной, поэтому при любых вызовах не нужно ее ждать. - person nnnnnn   schedule 09.04.2017