JavaScript Async / Await console.log () в массиве возвращает пустой - PullRequest
0 голосов
/ 22 января 2020

Здравствуйте, сообщество переполнения стека, я пришел к вам с проблемой, связанной с JS async / await. Я пытаюсь вызвать функцию asyn c, а затем записать в массив, куда функция asyn c передает результаты на консоль. Если я так называю это прямо в консоли:

console.log (Page.data) - я вижу, что это приводит к результатам, но если оно вызывается нажатием кнопки, оно записывает пустой массив.

// It is a nested object so do not worry if you don't exactly understand where Page.data comes from
Page.data = []

async function f1() {
  // Fetch JSON data
  // Process data 
  // Pushes at some point to the Page.data array
}
async function f2() {
  // Fetch JSON data
  // Process data 
  // Pushes at some point to the Page.data array
}
async function f3() {
  // Fetch JSON data
  // Process data 
  // Pushes at some point to the Page.data array
}

async function load(loader) {
    let fn = async function() {};
    if(condition1) fn = f1;
    else if(condition2) fn = f2;
    else fn = f3;

    // This is the line that makes me problems
    // According to documentation async functions return a promise
    // So why would the array in the case be empty?
    // Since I am telling it to display after the function is done
    await fn(loader).then(console.log(Page.data))
}

Это всего лишь шаблон моего кода и логика c. Я надеюсь, что вы можете понять, куда я иду. Ваша помощь будет высоко ценится.

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Выражение await заставляет асинхронную c функцию приостановить выполнение до тех пор, пока не будет выполнено обещание (то есть выполнено или отклонено), и возобновить выполнение асинхронной функции c после выполнения. При возобновлении значение выражения await совпадает со значением выполненного обещания.

Например (это пример MDN с некоторыми добавленными комментариями):

function resolveAfter2Seconds(x) { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  // note that here, you are "awaiting" the RESOLVED RESULT of the promise.
  // there is no need to "then" it.
  var x = await resolveAfter2Seconds(10);
  // the promise has now already returned a rejection or the resolved value. 
  console.log(x); // 10
}

f1();

Таким образом, вы бы "ожидали" "ваша функция, которая будет задерживать выполнение до тех пор, пока обещание не разрешит или не отклонит. После этой строки вы запустите свой console.log, и он будет регистрироваться, как ожидается. Краткий ответ: «удалите тогда».

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

0 голосов
/ 22 января 2020

проблема в том, что вы можете использовать then с await для того же метода, давайте проверим некоторые примеры, предоставленные MDN :

это рабочий Promise с использованием async/await:

let myFirstPromise = new Promise((resolve, reject) => {
  setTimeout(function() {
    resolve("Success!");
  }, 250)
})

const functionCaller = async() => {
  const result = await myFirstPromise
  console.log("the result: ", result);
}

functionCaller();

вы пытаетесь это:

let myFirstPromise = new Promise((resolve, reject) => {
  setTimeout(function() {
    resolve("Success!");
  }, 250)
})

const functionCaller = async() => {
  // you are not returning anything here... actually you are not doing anything with the response. despite it shows something, it is not sending any response
  await myFirstPromise.then(console.log("something happened"))

}
// then this function doesn't really get a value.
functionCaller();

, поэтому, что вам нужно сделать при вызове load, изменить его следующим образом:

async function load(loader) {
    let fn = async function() {};
    if(condition1) fn = f1;
    else if(condition2) fn = f2;
    else fn = f3;

    return await fn(loader)
}
...