我正在做这样的事情
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
解决后才能执行命令。
根据接受的答案和我以前的更新,我想到了这个
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
将返回相同的承诺,但是,如果未在给定的超时值中解决承诺,则承诺将被自动拒绝。
您应该通过转过头的“ pass命令拒绝”来得到一些有用的东西。换句话说,响应kill()
命令拒绝。
如您所知,问题在于fn()
应该返回一个Promise,而Promise不会自然地传达相应命令的.kill()
方法。但是,javascript允许将属性(包括函数(作为方法))动态附加到对象。因此,添加.kill()
方法很简单。
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();
}
});
...
var promise = deferred.promise;
// Now monkey-patch the promise with a .kill() method that fronts for command.kill() AND rejects the Deferred.
promise.kill = function() {
command.kill();
deferred.reject(new Error('killed')); // for a more specific error message, augment 'killed' with something unique derived from `param`.
}
return promise;
};
var promise1 = fn('command1');
var promise2 = fn('command2');
Q.all([promise1, promise2]).spread(...).catch(...);
promise1.kill()
否则promise2.kill()
将导致error.message
在捕获处理程序中出现“被杀死”的情况。
这两个杀人事件可以适当地称为,例如...
if(...) {
promise1.kill();
}
if(...) {
promise2.kill();
}
另外,这些.kill()
方法也可以干净地分离,而无需这样做.bind()
,例如:
doSomethingAsync(...).then(...).catch(promise1.kill);
doSomethingElseAsync(...).then(...).catch(promise2.kill);
请注意,fn()
任何数量的通话将工作,而不需要外部瓦尔command1
,command2
等等。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句