如何同时从函数返回值和承诺?

罗伯特·科安尼(RóbertKohányi)

我正在做这样的事情

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()我曾考虑过传递commandresolve,但之后可能再也不会调用它了。我也可以传递commandreject,以便在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解决了),因为该过程已在途中,当我通过promiseCommand1promiseCommand2Q.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]);
  })
]);

更正

在接受答案的评论部分,我被告知来电rejectfn,以防止我的代码挂起,因为挂起的承诺永远。我已经解决了以下问题

  command.promise = deferred.promise.timeout(...);
  return command;
};

使用timeout将返回相同的承诺,但是,如果未在给定的超时值中解决承诺,则承诺将被自动拒绝。

漫游者1888

您应该通过转过头的“ 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()任何数量的通话将工作,而不需要外部瓦尔command1command2等等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从承诺函数返回值

来自分类Dev

如何获取返回承诺的异步函数的返回值

来自分类Dev

如何获取返回承诺的异步函数的返回值

来自分类Dev

如何在此函数中返回值而不是承诺?

来自分类Dev

承诺的返回值

来自分类Dev

如何从函数返回值

来自分类Dev

如何从另一个函数内的承诺返回值?

来自分类Dev

如何从QThread和Queue运行的函数中返回值

来自分类Dev

如何添加指向函数和返回值的指针?

来自分类Dev

在函数返回值之前等待承诺的解决

来自分类Dev

蓝鸟承诺函数具有返回值

来自分类Dev

为什么异步函数返回值的承诺而不是直接返回值?

来自分类Dev

在javascript中返回值和/或违反承诺

来自分类Dev

如何让函数同时返回数组的索引和值?

来自分类Dev

如何在运行函数的同时在python中返回值

来自分类Dev

从函数返回值和语句

来自分类Dev

结构和函数返回值

来自分类Dev

函数返回值(char和整数)

来自分类Dev

Mips函数参数和返回值

来自分类Dev

承诺解决后,如何返回值Angular Typescript?

来自分类Dev

从函数返回承诺值

来自分类Dev

如何从_calling_函数返回值?

来自分类Dev

如何模拟类的函数的返回值?

来自分类Dev

如何终止递归函数并返回值

来自分类Dev

如何从EventEmitter函数返回值?

来自分类Dev

如何从gwidgets中的函数返回值

来自分类Dev

如何从扩展的casperjs函数返回值?

来自分类Dev

如何从函数中的exec返回值?

来自分类Dev

如何从Node的父函数返回值?