Как избавиться от асинхронности в функции?

Скажем, у меня есть этот код:

const myFunction = async => {
  const result = await foobar()
}

const foobar = async () => {
  const result = {}
  result.foo = await foo()
  result.bar = await bar()
  return result
}

А я хочу вот это:

const myFunction = () => {
  const result = foobar()
}

Я пробовал обернуть foobar вот так:

const foobar = async () => {
  return (async () => {
    const result = {}
    result.foo = await foo()
    result.bar = await bar()
    return result
  })()
}

Но это все еще возвращает обещание

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

Проблема в том, что моя функция - это асинхронная функция, и она вернет обещание, но должна вернуть undefine. Мне нужно избавиться от асинхронности в моя функция.

Обновлено: как сказал Себастьян Шпейтель, я хочу преобразовать моя функция для синхронизации

Изменить 2: Шилли, я использую nightwatch для теста end2end, nightwatch вызовет myFunction (), если нет ошибок при выполнении функции, она будет работать отлично, если есть ошибка, тогда виртуальные машины nightwatch будут работать вечно, а не останавливаться, эта проблема происходит, если вызываемая функция является асинхронной.

Чтобы снова синхронизировать асинхронную функцию, вам нужно либо использовать обратный вызов, либо время (true), чтобы предотвратить выполнение кода, пока обещание не будет разрешено

Sebastian Speitel 03.12.2018 13:23

Что вы имеете в виду, говоря об избавлении от асинхронности? Вы хотите, чтобы ваш код останавливал все выполнение до завершения foo() и bar()? Что внутри функций foo() и bar()? Можете ли вы их переписать, чтобы обещания не возвращались?

Kokodoko 03.12.2018 13:28

Чтобы переписать вашу функцию в режиме синхронизации, вы должны синхронизировать функции foo () и бар(). Если эти функции являются внешним API, вы должны проверить, есть ли версия для синхронизации. Имейте в виду, что если вы переписываете в режиме синхронизации, это будет разумно медленнее.

Mario Santini 03.12.2018 13:29

Не могли бы вы подробнее объяснить контекст, почему это нужно удалить? Поскольку то, что вы спрашиваете, довольно своеобразно, обычно люди хотят, чтобы это было наоборот, поэтому это может быть вопрос x / y. Нам нужно знать, что делает foobar (), чтобы знать, можно ли его превратить в обратный вызов.

Shilly 03.12.2018 13:33

@Shilly отредактировал, спасибо

José Sánchez 03.12.2018 13:38
Поведение ключевого слова "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) для оценки ваших знаний,...
3
5
647
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Любая функция, помеченная как async, вернет обещание. Этот:

const foobar = async () => {
  return 7;
}

Будет ли возвращено Promise 7. Это полностью не зависит от того, является ли функция, вызывающая foobar, async или нет, использует ли await или нет при ее вызове.

Итак, ваша проблема не (только) в myFunction: foobar использует async, что заставляет его всегда возвращать Promise.

Так вот, сказал это, ты, наверное, не сможешь достичь того, чего хочешь. Асинхронное ожидание только синтаксический сахар для обещаний. Вы пытаетесь использовать вернуть синхронное значение из асинхронной операции, а это в основном запрещено в javascript.

Здесь отсутствует очень важное понимание между синхронной и асинхронной природой кода.

Не каждую асинхронную функцию можно преобразовать в синхронную функцию. Вы можете использовать шаблон обратного вызова вместо await / async, но я сомневаюсь, что это будет вам полезно.

Вместо этого я бы рекомендовал вам просто использовать await, как в вашем первом примере кода, и оставить функции как асинхронные, это не должно повредить вашей логике.

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

Вы изучали возможность использования .executeAsync (), а затем обещание вызывать обратный вызов .done ()? Таким образом, должна быть возможность обернуть foobar и просто сохранить либо async, либо любые вызовы .then () внутри этой оболочки.

Мои знания о ночном дозоре очень устарели, но, возможно, что-то вроде:

() => {
  client.executeAsync(( data, done ) => {
    const result = await foobar();
    done( result );
  });
};

или:

  () => {
    client.executeAsync(( data, done ) => foobar().then( result => done( result )));
  };

Если это не работает с изменением функции .executeAsync на .perform, просто замените .executeAsync на .perform, и он работает.

José Sánchez 12.12.2018 16:42

Чтобы преобразовать асинхронную функцию в обычную синхронную функцию, вам просто нужно отбросить ключевое слово async и, как результат, все ключевые слова await в этой функции.

const myFunction = async () => {
    const result = await foobar();
    // ...
    return 'value';
};

// becomes

const myFunction = () => {
    const result = foobar();
    // ...
    return 'value';
};

Однако вы должны помнить одно простое правило.

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

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

Следующий код дает вам пример для вашей ситуации, предполагая, что возвращаемое значение моя функция не зависит от разрешенного обещания.

const myFunction = () => {
    const result = foobar();

    result.then(data => doSomethingElse(data))
          .catch(error => console.error(error));

    return 'some value not dependent on the promise result';
};

Если вы хотите узнать больше об обещаниях, я предлагаю проверить страницы гид обещаний и async / await.

Проверь это

    function foo(){
      return 'foo'
    }
    function bar(){
      return 'bar'
    }
    const foobar = () => {
        return new Promise((resolve)=>{
          let result = {}
          result.foo = foo()
          result.bar = bar()
          return resolve(result)
        })
    }

    const myFunction = () => {
      const result = foobar()
      let response = {}
      result.then(val=>{
        response = Object.assign({}, val);
        return response
      });
    }

    var test = myFunction()
    console.info(test)

Имейте в виду, что моя функция не имеет возвращаемого значения и поэтому вернет undefined.

3limin4t0r 03.12.2018 14:14

возвращает ли foo и bar обещание, или они возвращают нормальные значения

decodedxclusive 03.12.2018 14:23

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