Мне нужно изменить существующий код для поддержки синхронных и асинхронных результатов. Хотя я легко могу обрабатывать Task
и await
в C #, даже после прочтения многого из MDN и других страниц, я просто не могу разобраться с JavaScript Promise
.
Существующий код выглядит следующим образом:
function dispatchCall() {
// ...
try {
let result = fn.apply(context, args);
if (result !== undefined) {
return { status: 0, result: result };
}
return { status: 0 };
}
catch (err) {
if (typeof err === "object") {
return { status: 400, errorMessage: err.name + ", " + err.message, stack: err.stack };
}
return { status: 400, errorMessage: err };
}
}
fn
- вызываемая функция. Он определяется пользователем моего API, поэтому я не знаю, что он будет делать. На данный момент он всегда будет возвращать значение или выбрасывать исключение. Это значение будет помещено в объект сообщения, который передается удаленному абоненту dispatchCall
.
Теперь fn
необходимо вернуть Promise
, поскольку он должен использоваться в асинхронном рабочем процессе, где результат не доступен сразу.
Мне нужно проверить, является ли result
Promise
(или "тогда") и действовать соответственно. В этом случае, когда обещание результата разрешено, мне нужно обернуть значение результата в соответствующий объект сообщения и передать его как очередное обещание вызывающей стороне dispatchCall
. Тогда я легко справлюсь с этим.
Это то, что "передать и изменить значение" я не могу решить.
Вот как я бы начал:
function dispatchCall() {
// ...
try {
let result = fn.apply(context, args);
// --------------------------------------------------
if (result && typeof result.then === "function") {
result.then(function (result) {
// Like so?
if (result !== undefined) {
return { status: 0, result: result };
}
return { status: 0 };
})
.catch(function (err) {
// Does this catch errors?
if (typeof err === "object") {
return { status: 400, errorMessage: err.name + ", " + err.message, stack: err.stack };
}
return { status: 400, errorMessage: err };
});
return new Promise(function(resolve, reject) {
// What about this?
// When should I call resolve and reject and with what arguments?
});
// Must return a Promise and not continue at this point!
}
// --------------------------------------------------
if (result !== undefined) {
return { status: 0, result: result };
}
return { status: 0 };
}
catch (err) {
if (typeof err === "object") {
return { status: 400, errorMessage: err.name + ", " + err.message, stack: err.stack };
}
return { status: 400, errorMessage: err };
}
}
Как это должно быть склеено?
Посмотрев таблицы поддержки, я решил отказаться от поддержки Internet Explorer и использовать обещания ES6. Внешняя библиотека не задействована. В случае, если какой-либо IE выполнит это, он должен продолжать работать с синхронными функциями, и ему разрешается сбоить с асинхронным кодом.
Моими целевыми средами являются браузеры и Node.js.