Javascript 调用异步函数的循环

Javascript 调用异步函数的循环,javascript,firefox-addon,firefox-addon-sdk,Javascript,Firefox Addon,Firefox Addon Sdk,问题简介 我需要在循环中调用异步函数,直到满足条件为止。此特定函数向网站form.php发送POST请求,并对响应执行一些操作,响应是一个JSON字符串,表示具有id字段的对象。因此,当该id为null时,外部循环必须结束。该函数执行如下操作: 函数异步函数(会话){ (新要求)({ url:form.php, 内容:“sess=“+会话, 未完成:功能(响应){ var response=response.json; if(response.id){ doStaff(response.msg)

问题简介

我需要在循环中调用异步函数,直到满足条件为止。此特定函数向网站form.php发送POST请求,并对响应执行一些操作,响应是一个JSON字符串,表示具有id字段的对象。因此,当该id为null时,外部循环必须结束。该函数执行如下操作:

函数异步函数(会话){
(新要求)({
url:form.php,
内容:“sess=“+会话,
未完成:功能(响应){
var response=response.json;
if(response.id){
doStaff(response.msg);
}否则{
//断环
}
}
})).get();
}   
注意:虽然我发现了为Firefox实现附加组件的问题,但我认为这是一个普遍的javascript问题


递归实现循环

我曾经尝试过通过递归实现循环,但是没有成功,我不确定这是不是正确的方法

。。。
if(response.id){
doStaff(response.msg);
异步功能(会话);
}否则{
//断环
}
...
使用JSF

我还尝试了JSF库:

延迟。定义(此);
//实例化一个新的延迟对象
var deferred=新的deferred();
//主循环:当我们收到异常时停止
Deferred.loop(1000,函数(){
异步功能(会话,延迟);
延期归还;
}).
错误(函数(){
log(“循环完成!”);
});
然后打电话:

。。。
if(response.id){
doStaff(response.msg);
d、 call();
}否则{
d、 失败();
}
...

我实现了序列化,但每次迭代都会重复前面的调用。例如,如果它是第三次调用asyncFunction,它将在迭代1和2中使用相应的参数调用同一个函数。

您的问题不太清楚,但基本架构必须是异步操作的完成事件处理程序必须决定是重试还是简单返回。如果操作的结果需要再次尝试,那么处理程序应该调用父函数。如果没有,那么通过简单地退出循环就会结束


在JavaScript中,您不能用任何看起来像简单“循环”结构的东西编写这样的代码,因为操作是异步的。操作结果不会以允许循环机制对结果执行测试的方式发生;在结果可用之前,循环可能会运行数千次迭代。换句话说,您不需要“等待”带有代码的异步操作。您可以无所事事地等待,并允许注册的事件处理程序在结果准备就绪时接管。

您的问题并不完全清楚,但基本架构必须是异步操作的完成事件处理程序必须决定是否重试或只是返回。如果操作的结果需要再次尝试,那么处理程序应该调用父函数。如果没有,那么通过简单地退出循环就会结束


在JavaScript中,您不能用任何看起来像简单“循环”结构的东西编写这样的代码,因为操作是异步的。操作结果不会以允许循环机制对结果执行测试的方式发生;在结果可用之前,循环可能会运行数千次迭代。换句话说,您不需要“等待”带有代码的异步操作。您可以无所事事地等待,并允许注册的事件处理程序在结果准备就绪时接管。

如果我正确理解您想要做的事情,延迟是一种很好的方法。下面是一个使用jQuery的示例,它内置了延迟功能(
jQuery.Deferred

超时用于模拟http请求。当每个超时完成(或http请求完成)时,将返回一个与http请求结果相同的随机数

根据请求的结果,您可以决定是需要另一个http请求还是要停止

尝试下面的代码片段。包括jQuery文件,然后是代码段。它在控制台中不断打印值,并在达到零后停止

这可能需要一些时间来理解,但很有用

$(function() {

    var MAXNUM = 9;

    function newAsyncRequest() {
        var def = $.Deferred(function(defObject) {
            setTimeout(function() {
                defObject.resolve(Math.floor(Math.random() * (MAXNUM+1)));
            }, 1000);
        });

        def.done(function(val) {
            if (val !== 0)
                newAsyncRequest();
            console.log(val);
        });

    };

    newAsyncRequest();
});
根据@canuckistani的建议进行更新

@卡努基斯塔尼。对于这个问题,解决方法更简单。如果不使用Deferred,上面的代码片段将变成以下内容。对不起,我让你找到了更难的解决办法

$(function() {

    var MAXNUM = 9;

    function newAsyncRequest() {
        setTimeout(function() {
            var val = Math.floor(Math.random() * (MAXNUM+1));
            if (val !== 0)
                newAsyncRequest();
            console.log(val);
        }, 1000);
    }

    newAsyncRequest();

});

如果我正确理解了您想要做的事情,延迟是一个好方法。下面是一个使用jQuery的示例,它内置了延迟功能(
jQuery.Deferred

超时用于模拟http请求。当每个超时完成(或http请求完成)时,将返回一个与http请求结果相同的随机数

根据请求的结果,您可以决定是需要另一个http请求还是要停止

尝试下面的代码片段。包括jQuery文件,然后是代码段。它在控制台中不断打印值,并在达到零后停止

这可能需要一些时间来理解,但很有用

$(function() {

    var MAXNUM = 9;

    function newAsyncRequest() {
        var def = $.Deferred(function(defObject) {
            setTimeout(function() {
                defObject.resolve(Math.floor(Math.random() * (MAXNUM+1)));
            }, 1000);
        });

        def.done(function(val) {
            if (val !== 0)
                newAsyncRequest();
            console.log(val);
        });

    };

    newAsyncRequest();
});
根据@canuckistani的建议进行更新

@卡努基斯塔尼。对于这个问题,解决方法更简单。如果不使用Deferred,上面的代码片段将变成以下内容。对不起,我让你找到了更难的解决办法

$(function() {

    var MAXNUM = 9;

    function newAsyncRequest() {
        setTimeout(function() {
            var val = Math.floor(Math.random() * (MAXNUM+1));
            if (val !== 0)
                newAsyncRequest();
            console.log(val);
        }, 1000);
    }

    newAsyncRequest();

});

谢谢你们的帮助