Попытка использовать Async и Await из разных функций

Хотя я думал, что правильно использую ключевые слова Async и Await, похоже, что я делаю что-то не так.

Я использую PouchDB, отличную базу данных Javascript, которая синхронизируется с CouchDB. PouchDB использует обещания для многих своих функций и имеет встроенную поддержку Async и Await. Например, чтобы получить основную информацию о базе данных, вы должны использовать следующий код:

    db.info().then(function (info) {
  console.info(info);
})

Я это понимаю, и это работает. Но если я попытаюсь поместить это в функцию, а затем вызвать эту функцию, все пойдет наперекосяк. И я уверен, что проблема во мне, а не в PouchDB...

function getLocalDBInfo(db){

  try {
    db.info().then(function (info) {
      return info;
    });
  } catch (error) {
    console.info("can't get local DB info: ", error);
  }
}

async function testing(db){
  try {
    var info=await getLocalDBInfo(db);
    await console.info("DB info = ", info);
    await console.info("Doc count= ", info.doc_count);
  }
  catch(err){
    console.info("error = ",err);
  }

  //info contains...
    //{"doc_count":0,"update_seq":0,"db_name":"kittens"}
}

testing(MY_db);

Если я зарегистрирую info внутри функции getLocalDBInfo, она в конечном итоге (то есть после выполнения обещания) выведет info на консоль. Но журналы внутри функции testing немедленно возвращаются с undefined. Для меня имеет смысл, что они возвращаются undefined, потому что они возвращаются немедленно, но я пытался заставить их ждать info, используя async и await. Любые предложения относительно того, что я делаю неправильно?

getLocalDBInfo не помечен как асинхронный, плюс вам действительно нужно return что-то вроде return await db.info();
crashmstr 28.05.2019 19:50

@crashmstr Большое спасибо за ответ. Я не помечал getLocalDBInfo как асинхронный, потому что он использует обычную структуру обещаний и, согласно PouchDB, является обещанием. Может быть, я ошибался? Я думаю, что информация является результатом обещания, а не самого обещания. Если я регистрирую информацию, она в конечном итоге показывает выполненное обещание в консоли, поэтому информация в конечном итоге приводит к чему-то, но вы говорите, что возврат самого обещания, а не только результата, - это путь?

robert smith 29.05.2019 00:23
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
129
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

getLocalDBInfo() не возвращает обещание, поэтому вы не можете его дождаться.

с помощью async/await вы можете:

async function getLocalDBInfo(db){
    try{
       return await db.info()
    } catch (err){
       console.info("can't get local DB info: ", error);
    }
}

вы также можете использовать новое обещание

Я отметил это как решение, но все ответы говорят об одном и том же: вернуть обещание, а не результат обещания. В нескольких ответах предлагалось пометить функцию getLocalDBInfo как Async, но, в конце концов, в этом не было необходимости, и единственное требуемое изменение — это return db.info(). Я подозреваю, что не было необходимости помечать функцию getLocalDBInfo как асинхронную, потому что db.info() уже является обещанием через API PouchDB, но я рад, что меня исправили.

robert smith 29.05.2019 00:44

вы правы, в примере я разрешаю db.info внутри getLocalDBInfo и возвращаю новое обещание, если вы не делаете getLocalDBInfo асинхронным, вы просто передаете обещание db.info вокруг

Lordie 29.05.2019 03:01

Я сделал это, чтобы обработка ошибок могла происходить в функции-оболочке, поскольку блоки try-catch запускаются, когда промисы разрешаются.

Lordie 29.05.2019 03:07

Отличный материал. Это имеет смысл для меня. Спасибо за ваши ответы. Я пытаюсь лучше понять этот материал (я сделал несколько руководств, просмотрел спецификацию, провел дополнительные исследования и поэкспериментировал с ней), но я думаю, что все еще могу думать слишком последовательно (вероятно, поэтому я предпочитаю Async/Await) .

robert smith 29.05.2019 17:25

Вам нужно вернуть значение из внешней функции getLocalDBInfo

function getLocalDBInfo(db) {
  return new Promise((resolve, reject) => {
    db.info()
      .then(info => resolve(info))
      .catch(err => reject(err))
  })
}

getLocalDBInfo генерирует промис, прикрепляет к нему обратный вызов, а затем возвращает undefined. Он не возвращает выполненное обещание, и вы не можете ждать undefined (ну, вы можете, но это ничего не сделает).

Вам нужно изменить getLocalDBInfo на return обещание.

Кроме того, почему у вас есть блок then с подписью info => info? Все, что нужно сделать, это развернуть асинхронное значение, а затем снова его обернуть. Вы можете полностью опустить обратный вызов then.

Точно так же вы уверены, что вам нужно обернуть вызов db.info в try/catch? Интересно, не собираетесь ли вы вместо этого использовать здесь promise.catch. Конструкция try/catch захватывает отказы обещаний только тогда, когда awaiting выражение.

Спасибо за ответ, который был полезен и в конечном итоге привел к тому, что у меня все заработало. Простите, что, несомненно, является очень простым, смущающе простым вопросом, но я думал, что цель синтаксиса .then состоит в том, чтобы дождаться разрешенного обещания, а затем что-то сделать с этим результатом. Затем я рассудил, очевидно, ошибочно, что если я поместил оператор return в обратный вызов .then, он вернет результат обещания (т.е. info). Можете ли вы указать мне на это мышление? Я знаю, что что-то упускаю, но не могу понять, что это может быть.

robert smith 29.05.2019 00:49

@robertsmith Итак, когда обещание разрешается со значением, .then отображает это значение в другое обещание. Но вам не нужно сопоставлять значение, вы можете просто дождаться обещания. Вы понимаете, что я имею в виду?

Jimmy Breck-McKye 29.05.2019 13:05

Да, я верю, что знаю. В этом есть смысл. Кажется, я делал дважды то, что нужно было сделать только один раз. Правильный? Извините, но еще один вопрос: если это сопоставляется с другим обещанием, какой вред будет в возврате этого обещания (кроме неэффективности, конечно)? Это новое обещание, которое я собирался вернуть return info? Я не понимаю, как это могло быть, потому что это не сработало так, как у меня было. Еще раз спасибо за ваше время и помощь.

robert smith 29.05.2019 17:23

Другие вопросы по теме