【问题标题】:How pass parameters to downstream function with done() or next()如何使用 done() 或 next() 将参数传递给下游函数
【发布时间】:2016-09-27 06:25:34
【问题描述】:

我是 next()、done() 等的新手,并且正在努力在串行执行/可能异步函数的链接之间传播参数。

我想强制串行执行 2 个函数,这样它们就可以用类似的方式调用:

f1('#{arg1a}', '#{arg1b}').done(
  f2('#{arg2a}', '#{arg2b}')
);

或类似:

f1('#{arg1a}', '#{arg1b}', '#{arg2a}', '#{arg2b}').done(f2);

传入的 arg 值是使用 JSF 从查询参数中收集的。

注意:

  • arg2aarg2b 在我的情况下与 arg1aarg1b 完全无关,f2 的调用不会以任何方式取决于 f1 中发生的事情,其他它必须在之后严格执行,即使 f1 通常是异步的。

  • 我还没有在 done() 中定义即时匿名函数或类似的函数,我希望能够使用一些已知参数调用库定义的函数。

在本例中,函数类似于:

function f1(arg1a, arg1b) {

   //do something with arg1a, arg1b

  return $.Deferred().resolve();
}

function f2(arg2a, arg2b) {
  // Do something with arg2a and arg2b AFTER f1 has fully run.
}

或类似:

function f1(arg1a, arg1b, arg2a, arg2b) {

   //do something with arg1a, arg1b

  // Somehow ensure f1 is finished then execute f2(arg2a, arg2b)
}

function f2(arg2a, arg2b) {
  // Do something with arg2a and arg2b AFTER f1 has fully run.
}

仅使用回调链接不适用于我正在处理的情况。另见:How link to and target/open a p:tab within an p:accordionPanel within a p:tab within a p:tabview

一个可接受的答案必须允许我有一个带有预定义参数的预定义函数 f2

【问题讨论】:

  • return $.Deferred().resolve() 没有意义,因为您正在同步调用 resolve,在这种情况下您甚至不需要处理此异步。您是否在 f1 中使用了异步函数?
  • 另外,您能否提供一个同步示例来说明您正在尝试做什么。类似于“如果这是同步的,我想这样做......”

标签: javascript jquery


【解决方案1】:

需要将参数传递给.resolve(),然后使用.then()

function f1(arg1a, arg1b) {

  return $.Deferred(function(dfd) {
    //do something with arg1a, arg1b
    // you can alternatively call `.resolve()` without passing parameters
    // when you are finished doing something with `arg1a`, `arg1b`,
    // which should call chained `.then()` where `f2` is called
    dfd.resolve(arg1a, arg1b)
  }).promise();
}

function f2(arg2a, arg2b) {
  // Do something with arg2a and arg2b AFTER f1 has fully run.
}

f1(arg1, arg2)
.then(function() {
  // call `f2` here
  f2('#{arg2a}', '#{arg2b}');
})
// handle errors
.catch(function(err) { // alternatively use `.fail()`
  console.log(err)
});

jsfiddle https://jsfiddle.net/wuy8pj8d/

【讨论】:

  • 我不明白您如何将 arg2a 和 arg2b 的实际值(最终由 f2 处理)传递给 f1(arg1, arg2).then(f2) ...
  • “我不明白你是如何为 arg2a 和 arg2b 传递实际值的” 你是什么意思?您可以将所需的任何值传递给.resolve()
  • arg2aarg2b 在我的情况下与 arg1aarg1b 完全无关。当您调用 f1(arg1a,arg1b).then(f2) .. 时,不会有任何时刻从 arg2a、arg2b 的 JSF 参数中收集到的值被注入。它们甚至不会出现在您的调用/调用代码中。
  • "在我的情况下,arg2a 和 arg2b 与 arg1a 和 arg1b 完全无关" 同样,您可以将任何需要的值或不传递值传递给 .resolve() ;当.resolve() 被调用时,.then() 被调用,f2 作为参数。您在f2 中包含了参数,尽管它们不必是从f2 返回的值。这些值不必是arg1aarg1b。 jsfiddle 是为了演示模式以满足原始问题 “f2 的调用不以任何方式依赖于 f1 中发生的事情,除非它必须在之后严格执行” 中描述的要求
  • 谢谢,现在接受了,您已经对其进行了编辑,以正确处理和演示调用附加参数以提供给f2(因此其他读者可以关注)。我在我的系统中点击了这个.then(...).catch is not a function,所以我使用了fail(),然后它运行了。 then() 策略不能解决 my real world app Primefaces nested tab problem,但您的解决方案至少使我能够测试该策略(并了解有关 then() 和 Promises 的更多信息)。
【解决方案2】:

除了忘记将将来要执行的代码(最终调用 done 时)包装在函数中之外,您几乎做对了:

f1('#{arg1a}', '#{arg1b}').done(function(){
  f2('#{arg2a}', '#{arg2b}')
});

这也适用于常规回调。例如,假设您已将 f1 定义为接受回调而不是承诺,那么您会这样做:

f1('#{arg1a}', '#{arg1b}',function(){
  f2('#{arg2a}', '#{arg2b}')
});

这里没有什么特别的。强制回调接受自定义参数没有单独的语法,只需将其包装在另一个函数中即可。

由于闭包,这也适用于变量:

var a='#{arg1a}', b='#{arg1b}';
var c='#{arg2a}', d='#{arg2b}';

f1(a,b).done(function(){
  f2(c,d)
});

变量cd 可以在done() 中访问。

【讨论】:

  • 感谢您提供的替代答案,这肯定(如来自@guest271314 的已修改已接受答案)使f2 的值可以正常使用。但是,与next(callback 方法一样,在我的real problem involving a Primefaces web app 中,f2 之后的done(f1 完成之前运行,因此某些选择器失败(因为它们还不能用于选择)。但这超出了这个问题的范围。
  • @WebelITAustralia-upvoter:这个问题的问题在于,您在等待的任何事情完成之前都调用了callback。因此它不起作用。回调的目的是让您可以将其传递给您正在等待的东西。如果那个东西没有为你提供回调或承诺,那么你必须诉诸使用setTimeout 来轮询 DOM 并等到你等待的东西存在。
猜你喜欢
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 2012-02-05
  • 2014-06-04
相关资源
最近更新 更多