gpt4 book ai didi

jquery - 使用 Q.js "then"不带括号调用函数时遇到困难

转载 作者:行者123 更新时间:2023-12-01 07:12:25 24 4
gpt4 key购买 nike

我已经组装了一个在我的页面上使用的小工具,并且在大多数情况下它似乎都能正常工作,但是当我尝试将其插入Q.js<时,我的行为有点奇怪.

通常,据我了解,您可以通过这种方式调用函数。

Q(manager.tasks.init)
.then(manager.tasks.start)
.then(manager.tasks.fulfill)
.then(manager.tasks.finish);

但是我似乎无法做到这一点,相反我必须调用它们并像函数一样显式调用它们,就像这样。

Q(manager.tasks.init())
.then(manager.tasks.start())
.then(manager.tasks.fulfill())
.then(manager.tasks.finish());

完整的代码可以在这里看到;

jsBin

现在,我可以使用括号,但我不明白为什么它这样做。我想了解这里发生了什么,因此非常感谢任何信息。

最佳答案

在上面的评论和我的答案的评论中记录我们经历的一些事情......

您的上述解决方案实际上都没有正确编码。第一个有问题,因为当 Q 调用回调时,this 不会被设置属性。

当你这样做时:

Q(manager.tasks.init)
.then(manager.tasks.start)
.then(manager.tasks.fulfill)
.then(manager.tasks.finish);

Q 将调用这些方法,但 this 指针不会像您想要的那样设置为 manager.tasks。因此,当您在方法中执行此类操作时:

$(this).trigger("init:begin");

那么this将不是你想要的,它会抛出异常并停止执行。您可以通过执行以下操作来解决该问题:

Q(manager.tasks.init.bind(manager.tasks))
.then(manager.tasks.start.bind(manager.tasks))
.then(manager.tasks.fulfill.bind(manager.tasks))
.then(manager.tasks.finish.bind(manager.tasks));

这将导致 this 设置为 manager.tasks。或者,您可以删除这些方法中 this 的任何使用,以便它们成为静态方法(这似乎是您选择执行的操作)。

<小时/>

第二个没有像预期那样将函数引用传递给 .then()

当你这样做时:

Q(manager.tasks.init())
.then(manager.tasks.start())
.then(manager.tasks.fulfill())
.then(manager.tasks.finish());

JS 解释器立即调用您的函数(这就是当您将 () 放在末尾时发生的情况)并将这些函数的返回值传递给每个 .then( ) 行。那不是你想要的。 .then() 希望将函数引用传递给它,以便 Promise 库可以稍后执行该函数。在您的情况下,您的函数返回的 promise 不是您应该传递给 .then() 的内容。

因为这些方法中没有实际的异步操作,所以这似乎可以工作,因为它按顺序调用操作,但是只要其中任何一个方法中有一个实际解决 promise 的异步操作,它就不起作用正确。

<小时/>

对于您的fulfill方法的问题,它需要像这样,您在reduce操作中使用您创建的名为results的延迟/ promise 。我还更改了它以在 setTimeout() 之前运行reduce,因为它对我来说似乎更干净(更容易理解)。您正在设置要完成的所有工作,然后在 setTimeout() 中通过解决链中的第一个延迟来开始工作。

然后,它返回从 list.reduce() 操作返回的链式 Promise,并使用链式 .then() 处理程序来了解何时输出“fulfill:end”消息。

manager.tasks.fulfill = function () {
// alert the task manager that we're beginning this phase
$(manager.tasks).trigger("fulfill:begin");

// create a placeholder for the result of all of the items in the list
var results = Q.defer();

setTimeout(function(){
// resolve the first defer we created to
// let the `.then()` chain start to run
results.resolve();
}, 6000);

// now add all then `.then()` onto the results
// these functions won't run yet because the first defer has not yet resolved
return list.reduce(function(i, f) {
return i.then(f);
}, results.promise).then(function() {
// alert the task manager that we're ending this phase
// after all the callback promises have finished
$(manager.tasks).trigger("fulfill:end");
});
};
<小时/>

我认为如果您的回调返回这样的 promise ,.enqueue() 问题将会得到解决:

  manager.tasks.enqueue(function(deferred){
return function(){
setTimeout(function(){
console.log('test');
deferred.resolve();
}, 3000);
return deferred.promise;
};
});

如果是我,我可能会更改 .enqueue() 实现,以便它处理 promise 的返回(因为它是创建它的人),但这是一个快速的解决方案这是为了确保您的回调在执行时返回 promise 。

您可以在此处查看 jsFiddle 的派生 http://jsfiddle.net/jfriend00/JxJVs/实现这些更改后,可以生成您在 JPEG 中显示的精确输出。

关于jquery - 使用 Q.js "then"不带括号调用函数时遇到困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24664101/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com