Javascript for循环承诺 [英] Javascript for loop Promises

查看:66
本文介绍了Javascript for循环承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列像这样的网址

I have an array of urls like this

var urls = ["www.google.com", "www.yahoo.com"];

我想通过网址循环并在循环内执行异步任务而不是继续async任务完成之前的下一个项目。我知道你可以用承诺做到这一点,但我遇到了一些麻烦。这里我有什么

And I want to loop though the urls and perform an async task inside the loop and not move on to the next item until the async task has finished. I know you can do this with promises but I have having some trouble with it. Here what I have

var xmlReader = require('cloud/xmlreader.js');

function readResponse_async(xlmString) {
    var promise = new Parse.Promise();
    xmlReader.read(xlmString, function (err, res) {
        if(err) {
            promise.reject(err);
        } else {
            promise.resolve(res);
        }
    });
    return promise;
}

for (i = 0; i < urls.length; i++) {

    Parse.Cloud.httpRequest({
        url: unionUrls[i],
    }).then(function(httpResponse) {
            try {
//              console.log(httpResponse.text)
                return readResponse_async(httpResponse.text)
            } catch (e) {console.log(e)}

}

但是现在它不等待readResponse_async完成,我怎么能让它等待呢?

But right now it doesn't wait for the readResponse_async to finish, how can I have it wait for that?

谢谢

编辑

阅读完回复后,我保存到我的数据库,我有另一个像这样的数组

After reading the response I make a save to my database and I have another array like this

var location = ['USA', 'England'];

我这样保存

function saveLoc_async(data, location) {
var i3, i4, i5, m,
            TestItem = Parse.Object.extend("TestItem"),//can be reused within the loops?
            promise = Parse.Promise.as();//resolved promise to start a long .then() chain
        for (i3 = 0; i3 < data.count(); i3++) {
             (function(testItem) {
                        testItem.set("item", data.at(i));
                        testItem.set("location", location);
                        //build the .then() chain
                        promise = promise.then(function() {
                            return testItem.save();
                        });
                    })(new TestItem());
//************************
//CALL  retry(); here?
//**************************

}

因为你的回答我有

function retry() {
if (urlsUnion.length > 0) {
    var nextUrl = urlsUnion.pop();
    //********** ADDED LINE
    var nextLoc = location.pop();

    Parse.Cloud.httpRequest({
        url: nextUrl,
    }).then(function(httpResponse) {
        xmlReader.read(httpResponse.text, function (err, res) {
            if(err) {
                // show an error
            } else {
                //********** ADDED LINE
                saveLoc_async(res, nextLoc);
                retry();
            }
        });
    });
}
}

SO应该在哪里重试( ); go因为现在有了保存,有时它将第二个位置与第一个项目url之一?为什么会发生这种情况?

SO where should retry(); go because right now with the save sometimes it puts the second location with one of the first items url? why would that happen?

推荐答案

您的代码会立即触发两个网址,而不会在中间等待。

Your code fires both urls immediately, and does not wait in-between.

您需要做的是从阵列中删除第一个网址并将其解雇。在'then'分支中检查你是否仍然在数组中有url并重复。

What you would have to do is to remove the first url from the array and fire it. In the 'then' branch check if you still have url's in the array and repeat.

像这样(未经测试,编辑以使代码再次清理):

Like this (untested, edited to make the code clean again):

var xmlReader = require('cloud/xmlreader.js');

function readResponse_async(xlmString) {
    xmlReader.read(xlmString, function (err, res) {
        if(err) {
            // show an error
        } else {
            readFirstUrl();
        }
    });
}

function readFirstUrl() {
    if (urlsUnion.length == 0) {
        return;
    }
    var url = urlsUnion.pop();
    Parse.Cloud.httpRequest({
        url: url,
    }).then(function(httpResponse) {
        readResponse_async(httpResponse.text);
    });
}

readFirstUrl();

这篇关于Javascript for循环承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆