具有延迟的顺序承诺循环

时间:2017-01-24 05:05:31

标签: javascript promise

我正在尝试按顺序加载一系列“请求”,每个请求都被延迟隔开。

我正在使用promises,但由于某些原因,我遇到了并行执行请求而不是按顺序执行的问题。

我写了一些测试代码,如下所示。有用!它发出请求,处理它,timesOut 3秒钟,然后转到第二个请求。

<!-- DataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
    <property name="packagesToScan" value="net.softengine.edu.model"/>
</bean>

<!-- Transaction Manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- JPA Template -- >
<bean id="jpaTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

但是,只要我尝试将其置于任何类型的循环中,我的请求就会同时触发。超时调用发生在。

之后

我不确定我做错了什么,或者误解了。

var batches = [of_objects];
var sequence = Promise.resolve();
var self = this;

sequence
    //Create request for first batch
    .then( function(){
        return self._createRequestPromise(batches[0]);
    })
    //callback so we can update, returns nothing
    .then(callback)
    //add 3 sec timeout before next request
    .then(function(){
        return new Promise(function (resolve, reject){
            setTimeout(resolve, 3000);
        });
    })
    //Create request for second batch
    .then( function(){
        return self._createRequestPromise(batches[1]);
    })
    //callback so we can update, returns nothing
    .then(callback)
    //add 3 sec timeout before next request
    .then(function(){
        return new Promise(function (resolve, reject){
            setTimeout(resolve, 3000);
        });
    });

return sequence;

1 个答案:

答案 0 :(得分:3)

问题在于您没有更新sequence以包含任何连续的操作,因此所有这些操作都将链接到原始解决的承诺。没有任何东西可以延迟任何一个,所以他们立即执行。

您应该能够通过更新每个循环上的sequence变量来解决这个问题,这样您就可以链接到链的末尾:

//object I need to use to construct requests
var batches = [of_objects];
var sequence = Promise.resolve();
var self = this;

batches.forEach(function (batch){
    sequence = sequence            // <-- here
        //Function returns promise
        .then( function(){
            return self._createRequestPromise(batch); //this runs first 5x
        })
        //callback so we can update, returns nothing
        .then(callback)
        //add 3 sec timeout before next request
        .then(function(){
            return new Promise(function (resolve, reject){
                setTimeout(resolve, 3000); //this runs after 5x
            });
        });
});

return sequence;

就个人而言,我试图避免覆盖变量,因此在没有变量重新分配的情况下执行此操作的另一种方法是使用.reduce()

//object I need to use to construct requests
var batches = [of_objects];
var self = this;

return batches.reduce(function (last, batch){
    return last
        //Function returns promise
        .then( function(){
            return self._createRequestPromise(batch); //this runs first 5x
        })
        //callback so we can update, returns nothing
        .then(callback)
        //add 3 sec timeout before next request
        .then(function(){
            return new Promise(function (resolve, reject){
                setTimeout(resolve, 3000); //this runs after 5x
            });
        });
}, Promise.resolve());