Как обрабатывать промисы при использовании (вызов, привязка, применение) с функциями JavaScript?

У меня есть такая функция:

let maybeRun = function (cb: Function, allow: boolean, ctx: object = window) {
    return function () {
        if (!allow) return;

        cb.call(ctx, ...arguments);
        // cb.apply(ctx, arguments);
    };
};

В случае, если cb является синхронным, проблем нет, но как мне поступить в случае, если cb возвращает обещание (асинхронно)?

let cb = async ()=> {...};

let foo = maybeRun(cb, true);

await foo()

Я хочу, чтобы возвращаемая функция foo имела такое же поведение, как cb (синхронная или асинхронная).

Await ничего не делает с non-thenables, поэтому вы можете просто использовать await cb(...).

catgirlkelly 05.05.2022 18:04
Поведение ключевого слова "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) для оценки ваших знаний,...
0
1
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

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

let maybeRun = function (cb: Function, allow: boolean, ctx: object = window) {
    return function () {
        if (!allow) return; // *** See note below

        return cb.call(ctx, ...arguments);
// −−−−−^^^^^^
    };
};

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


В комментарии вы сказали:

i didn't write a return because the wrapped functions i need this function for have no returns

Это меняет ситуацию для вашего конкретного варианта использования: вы просто используете await при вызове функции:

let maybeRun = function (cb: Function, allow: boolean, ctx: object = window) {
    return async function () {
// −−−−−−−−^^^^^
        if (!allow) return;

        await cb.call(ctx, ...arguments);
// −−−−−^^^^^
    };
};

Теперь ваша функция (будучи async) всегда возвращает обещание, а в случаях, когда cb возвращает обещание (либо явно, либо потому, что это функция async), ваша функция будет ждать, пока это обещание будет выполнено, прежде чем вернуться, но не будет возвращать значение исполнения.

Обратите внимание, что даже с этим изменением cb вызывается синхронно, когда вы вызываете функцию-оболочку, полученную из maybeRun. Функция async работает синхронно до тех пор, пока ей не придется чего-то ждать в первый раз. Если cb является синхронным, он будет запущен во время этого начального синхронного выполнения оболочки.

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

modex98 05.05.2022 18:00

@modex98 - А, это меняет дело. Я обновлю.

T.J. Crowder 05.05.2022 18:00

Я уверен, что вы все равно можете написать перегрузки, чтобы различать синхронные/асинхронные обратные вызовы.

catgirlkelly 05.05.2022 18:04

О, я думал, мы говорим о типах, хе-хе ?

catgirlkelly 05.05.2022 18:07

@catgirlkelly - Боже мой. Я полностью прочитал за типами и тег [typescript]. Теперь я должен пересмотреть ответ снова. ;-D О, подождите, нет, я не знаю, потому что даже если бы мы могли писать перегрузки, нам все равно пришлось бы основывать реализацию на значении времени выполнения того, что она получила, и мы не можем обнаружить функцию, которая явно возвращает обещание (включая переданную функцию async). Тем не менее, ничего себе, когда я читаю сразу после типов. о_О

T.J. Crowder 05.05.2022 18:08

Нет ли внутреннего скрытого объекта AsyncFunction, похожего на функцию? Я помню, как сталкивался с этим в node.js. То же самое с AsyncGeneratorFunction и GeneratorFunction. Довольно дурацкая проклятая штука.

catgirlkelly 05.05.2022 18:14

@catgirlkelly — есть GeneratorFunction и AsyncGeneratorFunction, но речь идет о более общих параметрах типа, потому что в них есть нечто большее, чем базовые функции. Но, несмотря на это, эта информация о типе не будет у функции реализации во время выполнения, которая ей понадобится, если мы собираемся основывать решение на том, возвращать ли обещание на ее основе.

T.J. Crowder 05.05.2022 18:29

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