Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 03.07.2017, 16:01
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Асинхронный вызов в синхронный
Всем привет.

Есть такой код:
function mainProcess() {
	// изменять нельзя
	console.log("begin");
	console.log(asyncFunc());
	console.log("end");
}

function asyncFunc(result) {
	if (result !== undefined) {
		console.log("then");
		return result;
	}
	setTimeout(function() {
		//console.log("timeout done");
		asyncFunc("then");
		//result = "then";
	}, 2000);
}

mainProcess();
/*  Результат:
begin
undefined
end
then
*/


Можно ли, не изменяя mainProcess, сделать так, чтобы asyncFunc выполнялась как бы синхронно?
Т.е. результат должен быть такой:
/*
begin
then
end
*/

Последний раз редактировалось SergeyERjs, 03.07.2017 в 16:05. Причина: добавил [JS run]
Ответить с цитированием
  #2 (permalink)  
Старый 03.07.2017, 16:42
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Пробовал так:
function asyncFunc(result) {
	// if (result !== undefined) {
	// 	console.log("then");
	// 	return result;
	// }
	setTimeout(function() {
		console.log("timeout done");
		//asyncFunc("then");
		result = "then";
	}, 2000);
	var startTime = Date.now();
	while(Date.now() - startTime < 3000) {
		if (result !== undefined) {
			console.log("дождались");
			return result
		}
	}
	console.log("превышено время ожидания");
}

В этом случае таймер не срабатывает, пока не завершится цикл.

Последний раз редактировалось SergeyERjs, 03.07.2017 в 16:43. Причина: исправлены ошибки
Ответить с цитированием
  #3 (permalink)  
Старый 03.07.2017, 16:59
Аватар для EmperioAf
Профессор
Отправить личное сообщение для EmperioAf Посмотреть профиль Найти все сообщения от EmperioAf
 
Регистрация: 15.01.2015
Сообщений: 622

async function main() {
  console.log('begin');
  await wait(2000);
  console.log('end');
}

function wait(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

main().then(() => console.log('main is done'));
Ответить с цитированием
  #4 (permalink)  
Старый 03.07.2017, 17:13
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

EmperioAf,
как в resolve добавить console.log("then"); ?
Ответить с цитированием
  #5 (permalink)  
Старый 03.07.2017, 17:23
Аватар для EmperioAf
Профессор
Отправить личное сообщение для EmperioAf Посмотреть профиль Найти все сообщения от EmperioAf
 
Регистрация: 15.01.2015
Сообщений: 622

async function main() {
  console.log('begin');
  await asyncWork(10000);
  console.log('end');
}

function asyncWork(ms) {
  var i = 0;
  return new Promise(resolve => { 
    const foo = () => {
      if (i > 99) {
        resolve();
      } else {
        i++;
        console.log(`${i}% is done`);
        setTimeout(foo, ms / 100);
      }
    }
    foo();
  });
}

main().then(() => console.log('main is done'));
Ответить с цитированием
  #6 (permalink)  
Старый 03.07.2017, 17:26
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Спасибо, но в IE не работает
Ответить с цитированием
  #7 (permalink)  
Старый 03.07.2017, 17:29
Аватар для EmperioAf
Профессор
Отправить личное сообщение для EmperioAf Посмотреть профиль Найти все сообщения от EmperioAf
 
Регистрация: 15.01.2015
Сообщений: 622

SergeyERjs,
Babel не воспрещается, как и любой другой транспайлер, чтобы работало в IE.
Ответить с цитированием
  #8 (permalink)  
Старый 03.07.2017, 17:31
Аспирант
Отправить личное сообщение для Luca Посмотреть профиль Найти все сообщения от Luca
 
Регистрация: 20.06.2017
Сообщений: 69

Babel в помощь
'use strict';
var main = function () {
  var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            console.log('begin');
            _context.next = 3;
            return asyncWork(10000);

          case 3:
            console.log('end');

          case 4:
          case 'end':
            return _context.stop();
        }
      }
    }, _callee, this);
  }));

  return function main() {
    return _ref.apply(this, arguments);
  };
}();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function asyncWork(ms) {
  var i = 0;
  return new Promise(function (resolve) {
    var foo = function foo() {
      if (i > 99) {
        resolve();
      } else {
        i++;
        console.log(i + '% is done');
        setTimeout(foo, ms / 100);
      }
Ответить с цитированием
  #9 (permalink)  
Старый 03.07.2017, 17:33
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

EmperioAf,
понял, спасибо!
async function main() {
  console.log('begin');
  await wait(2000);
  console.log('end');
}

function wait(ms) {
  return new Promise(resolve => setTimeout(()=> {console.log("then");resolve()}, ms));
}

main().then(() => console.log('main is done'));
Ответить с цитированием
  #10 (permalink)  
Старый 03.07.2017, 17:37
Интересующийся
Отправить личное сообщение для SergeyERjs Посмотреть профиль Найти все сообщения от SergeyERjs
 
Регистрация: 03.07.2017
Сообщений: 19

Luca,
А не изменяя mainProcess? Или хотя бы не так сильно.

Дело в том, что asyncFunc используется много где по коду. Не хочется рефакторить 90% кода.

Вот такое изменение еще пойдет:
console.log('begin');
*!*
  await asyncWork(10000);
*/!*
  console.log('end');

Последний раз редактировалось SergeyERjs, 03.07.2017 в 17:39.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вызов функции через new Object() RblSb Общие вопросы Javascript 5 31.05.2015 19:12
Асинхронный вызов, помогите разобраться? ascherbakov AJAX и COMET 6 10.04.2014 09:20
XMLHttpRequest асинхронный вызов. Loki6999 Общие вопросы Javascript 2 16.10.2013 09:56
Асинхронный вызов толстых функций Rogov Dmitry Events/DOM/Window 15 02.08.2011 14:11