Асинхронный вызов в синхронный
Всем привет.
Есть такой код: 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 */ |
Пробовал так:
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("превышено время ожидания"); } В этом случае таймер не срабатывает, пока не завершится цикл. |
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')); |
EmperioAf,
как в resolve добавить console.log("then"); ? |
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')); |
Спасибо, но в IE не работает :(
|
SergeyERjs,
Babel не воспрещается, как и любой другой транспайлер, чтобы работало в IE. |
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); } |
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')); |
Luca,
А не изменяя mainProcess? Или хотя бы не так сильно. Дело в том, что asyncFunc используется много где по коду. Не хочется рефакторить 90% кода. Вот такое изменение еще пойдет: console.log('begin'); *!* await asyncWork(10000); */!* console.log('end'); |
Часовой пояс GMT +3, время: 13:45. |