Проблема, яку ви описуєте, двояка.
- Програма, яку ви пишете, повинна вести себе асинхронно в цілому, якщо дивитися зовні .
- Це повинно сайті виклику не бути видно, чи потенційно функціональний виклик передає контроль чи ні.
Є кілька способів цього досягти, але вони в основному зводяться до цього
- маючи кілька ниток (на деякому рівні абстракції)
- що мають декілька видів функцій на мовному рівні, всі вони називаються так
foo(4, 7, bar, quux)
.
Для (1) я збираю разом розгалуження та запуск декількох процесів, нерестування декількох потоків ядра та реалізацій зелених ниток, які планують потоки рівня мови та часу виконання на потоках ядра. З точки зору проблеми, вони однакові. У цьому світі жодна функція ніколи не відмовляється і не втрачає управління з точки зору своєї нитки . Сам потік іноді не має керування, а іноді не працює, але ви не відмовляєтесь від контролю над власною потоком у цьому світі. Система, що відповідає цій моделі, може мати або не мати можливість нерестувати нові потоки або приєднуватися до існуючих потоків. Система, що відповідає цій моделі, може мати або не мати можливість дублювати нитку, як у Unix fork
.
(2) цікаво. Для здійснення справедливості нам потрібно поговорити про форми введення та усунення.
Я покажу, чому неявне await
не можна додавати до такої мови, як Javascript, зворотним чином. Основна ідея полягає в тому, що, викриваючи обіцянки користувачеві та розрізняючи синхронний та асинхронний контексти, Javascript просочив деталі реалізації, що запобігає рівномірному поводженню синхронних та асинхронних функцій. Є й той факт, що ти не можешawait
можете обіцяти поза тілом функції асинхронізації. Ці варіанти дизайну несумісні з "роблячи асинхронність невидимою для абонента".
Ви можете ввести синхронну функцію за допомогою лямбда та усунути її за допомогою виклику функції.
Введення синхронної функції:
((x) => {return x + x;})
Усунення синхронної функції:
f(4)
((x) => {return x + x;})(4)
Ви можете порівняти це з введенням та усуненням асинхронних функцій.
Введення асинхронної функції
(async (x) => {return x + x;})
Усунення асинхоронної функції (примітка: дійсне лише всередині async
функції)
await (async (x) => {return x + x;})(4)
Основна проблема тут полягає в тому, що асинхронна функція - це також синхронна функція, що виробляє об'єкт, що обіцяє .
Ось приклад виклику асинхронної функції синхронно у репліку node.js.
> (async (x) => {return x + x;})(4)
Promise { 8 }
Можна гіпотетично мати мову, навіть динамічно набрану, де різниця між асинхронними та синхронними викликами функцій не видно на сайті виклику і, можливо, не видно на сайті визначення.
Отримавши подібну мову та знизивши її до Javascript, можливо, вам просто доведеться ефективно зробити всі функції асинхронними.