【发布时间】:2016-02-24 23:15:27
【问题描述】:
我正在做这样的事情
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;
})
]);
还有其他方法吗?
更新
从昨天开始我就想出了如何使用解构赋值(仍然不确定语法)
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]);
})
]);
更正
在已接受答案的评论部分,建议我在fn 中调用reject,以防止我的代码因为未决的承诺而永远挂起。我已经用以下方法解决了这个问题
command.promise = deferred.promise.timeout(...);
return command;
};
使用timeout 将返回相同的promise,但是如果promise 没有在给定的超时值内解决,promise 将被自动拒绝。
【问题讨论】:
-
promise2.then(Q.all([的问题在于.then的参数必须是函数 - 否则它们会被有效地忽略 -
@JaromandaX 是的,我的例子已经关闭。但是它很有教育意义:)
标签: javascript node.js promise q