javascript - вызвать syn c как асинхронную функцию - PullRequest
0 голосов
/ 17 февраля 2020

Я хочу вызвать функцию syn c как asyn c, не делая саму функцию асин c. Итак, что я в основном пытаюсь сделать, это: («asynccall» - это псевдокод для чего-то, вызывающего функцию asyn c)

asynccall doSomething(a, b, c);

function doSomething(a, b, c) {
   //doing something
}

самое близкое, что мне нужно сделать - это создать асин c функция, которая вызывает функцию syn c:

aDoSomething(a, b, c);

async function aDoSomething(a, b, c) {
   doSomething(a, b, c);
}

function doSomething(a, b, c) {
   //doing something
}

, которая работает, но я не хочу создавать эту избыточную функцию. Есть ли способ достичь того, что сделано в примере 2, способом, который выглядит как пример 1?

Ответы [ 4 ]

1 голос
/ 17 февраля 2020

Один из способов назвать что-то «позже», получив взамен обещание, - это использовать Promise.resolve().then:

function doSomething(a, b) {
     console.log("doing something");
     return a+b;
}

let result = Promise.resolve().then(() => doSomething(1, 2));

result.then(console.log);

console.log("synchronous code completed");

Но вы также можете использовать свою оригинальную идею, но с IIFE:

function doSomething(a, b) {
     console.log("doing something");
     return a+b;
}

let result = (async () => { 
    await null; 
    return doSomething(1, 2); 
})();

result.then(console.log);

console.log("synchronous code completed");

Если это все еще выглядит слишком много при записи, создайте обобщенную c функцию с именем asynccall, которую затем можно использовать для любого вызова функции:

function asynccall(f, thisArg, ...args) {
     return Promise.resolve().then(() => f.call(thisArg, ...args));
}

function doSomething(a, b) {
     console.log("doing something");
     return a+b;
}

let result = asynccall(doSomething, null, 1, 2);

result.then(console.log);

console.log("synchronous code completed");
0 голосов
/ 17 февраля 2020

Когда мне нужно, я делаю это так:

setTimeout(function() {
    // do your function
}, 0);

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

Редактировать: я забыл добавить ссылку (глупо с моей стороны): https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide (Микрозадача)

https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API (Задачи)

0 голосов
/ 17 февраля 2020

То, что вы пытаетесь сделать, означает возможное недопонимание того, как работает Javascript двигатель.

Javascript работает однопоточно. Это означает, что он может выполнять только одну операцию за раз (он обрабатывает операторы один за другим). Некоторое асинхронное c выполнение может быть достигнуто, но только когда задействованы операции ввода / вывода (ввода / вывода) или с использованием некоторых определенных API, таких как createTimeout() или createInterval().

Я рекомендую вам эта статья , чтобы лучше понять эту концепцию.

  • КРАТКИЙ ОТВЕТ:

Если не выполняются истинные асинхронные задачи (например, операции ввода-вывода) , тогда

ЭТО:

aDoSomething(a, b, c);

async function aDoSomething(a, b, c) {
   doSomething(a, b, c);
}

function doSomething(a, b, c) {
   // do something
}

- это то же самое (но излишне менее производительное), как это:

doSomething(a, b, c);

function doSomething(a, b, c) {
   // do something
}
  • ПРИМЕЧАНИЕ О ДРУГИХ ОТВЕТАХ:
doSomething(a, b, c);

function doSomething(a, b, c) {
    setTimeout(function() {
        // do something
    }, 0);
}

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

0 голосов
/ 17 февраля 2020

Упаковка вашей функции doSomething в функцию async больше ничего не делает. Если это соответствует вашим потребностям, то doSomething(a, b, c);

Асинхронная операция, которую вы выполняете в doSomething, не будет блокировать поток выполнения, остальная часть вашего кода выполнится, как только doSomething вернет что-то , что должно произойти, как только асинхронная задача была поставлена ​​в очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...