я делаю что-то вроде этогоКак вернуть значение и обещание от функции в одно и то же время?
var command1;
var command2;
var fn = function(param) {
var deferred = Q.defer();
var command = spawn(..., [
... passing different arguments based on param ...
]);
...
command.stdout.on('data', function(data) {
if (/... if process started successfully .../.test(data)) {
deferred.resolve();
}
});
...
if (param === 'command1') {
command1 = command;
} else {
command2 = command;
}
return deferred.promise;
};
Q.all([
fn('command1'),
fn('command2')
]);
и позже я звоню command1.kill()
и command2.kill()
. Я думал о прохождении command
до resolve
, но тогда он никогда не может быть вызван. Я мог бы также пройти command
до reject
, чтобы я мог позвонить kill
там, если что-то пошло не так, но это странно.
Как я могу вернуть command
и обещание звонящему по идиоматическому пути? Без условной части в fn
. Каковы возможности?
Я также думал о деконструкции функции присваивания ES6, но рассмотрим следующий
...
return [command, deferred.promise];
}
[command1, promiseCommand1] = fn('command1');
[command2, promiseCommand2] = fn('command2');
Q.all([
promise1,
promise2.then(Q.all([
promiseCommand1,
promiseCommand2
])
]);
, но это не удается (по крайней мере, в моем конкретном случае, когда команды не должны ждать, пока promise2
разрешен), потому что процессы уже на своем пути, когда я проходил promiseCommand1
и promiseCommand2
до Q.all
.
Не уверен, что я использовал правильный синтаксис разукрупнения.
Просто совал мне в голову
var command1;
var command2;
var fn = function(param, callback) {
var deferred = Q.defer();
var command = spawn(..., [...]);
...
callback(command);
return deferred.promise;
};
Q.all([
fn('command1', function(command) {
command1 = command;
}),
fn('command1', function(command) {
command2 = command;
})
]);
Любой другой путь?
Update
Со вчерашнего дня я понял, как я мог бы, возможно, использовать назначение деконструкции (до сих пор не уверен в синтаксисе)
Q.all([
promise1,
promise2.then(function() {
[command1, promiseCommand1] = fn('command1');
[command2, promiseCommand2] = fn('command2');
return Q.all([
promiseCommand1,
promiseCommand2
]);
})
]);
таким образом команды будут выполняться только после того, как promise2
является решена.
Решение
Основываясь на the accepted answer и моем предыдущем обновлении, я пришел с этим
command.promise = deferred.promise;
return command;
};
Q.all([
promise1,
promise2.then(function() {
command1 = fn('command1');
command2 = fn('command2');
return Q.all([command1.promise, command2.promise]);
})
]);
работ и, как представляется, кратким решением для меня. Я не хочу полагаться на ES6 для деконструирования задания. Кроме того, я не думаю, что могу использовать эту функцию, чтобы присвоить одно значение переменной, объявленной за пределами области действия, и кратко назначить другую в локальной области. Возврат
return {
command: command,
promise: deferred.promise
};
также является возможным решением, но менее кратким.
Q.all([
promise1,
promise2.then(function() {
var result1 = fn('command1');
var result2 = fn('command2');
command1 = result1.command;
command2 = result2.command;
return Q.all([result1.promise, result2.promise]);
})
]);
Коррекция
В разделе комментариев в принятом ответ я посоветовала позвонить reject
в fn
, чтобы предотвратить мой код повесить навсегда из-за отложенного обещания.Я решил эту проблему следующим
command.promise = deferred.promise.timeout(...);
return command;
};
Использование timeout
возвратит такое же обещание, однако, если обещание не будет решена в данном таймаута обещание будет отклонена автоматически.
проблема с 'prom2.then (Q.all ([' является то, что аргумент (ы) для '.then' ** MUST ** является функцией (-ами) - в противном случае они эффективно игнорируются –
@JaromandaX Да, мой пример был выключен. Однако это было образовательным :) –