简体   繁体   English

如何使用node.js Q在链执行期间插入promises?

[英]How to insert promises during chain execution using node.js Q?

I have a promise chain that requests an RSS URL, parses it for links, then needs to request each link. 我有一个承诺链,请求RSS URL,解析链接,然后需要请求每个链接。 The first part works great. 第一部分效果很好。 However I'm having trouble working out how to "insert the promises" that request each link that has been parsed. 但是,我无法解决如何“插入请求”,请求每个已解析的链接。

I started by generating a simple array of link URLs (preferred method) but couldn't make that work. 我开始生成一个简单的链接URL数组(首选方法),但无法使其工作。 The code now generates an array of promises to request each URL but I don't know how to make that work either. 代码现在生成一个promises数组来请求每个URL,但我不知道如何使这个工作。 Perhaps I need to use Q.all() but that seems to be for predetermined functions? 也许我需要使用Q.all(),但这似乎是预定的功能?

requestRss(rssSourceUrl)
.then(function(links) { 
    // ???
})
.catch(function(error) {
    console.log(error);
})
.done();

function requestRss(url) {
    var deferred = q.defer();
    request(url, function(err, resp, body) {
            if (err || resp.statusCode !== 200) {
                deferred.reject(new Error(resp.statusCode + ' ' + err + ' ' + body));
            } else {
                $ = cheerio.load(body);
                var linkRegex = /<link>([^<$]+)/gim;
                var someLinks = new Array();
                $('item').each(function() {
                    var match = linkRegex.exec($(this).html());
                    if (match) {
                        var link = match[1];
                        someLinks.push(
                            function() { requestSomeLink(link); }
                        );
                    }
                });
                deferred.resolve(someLinks);
            }
        });
    return deferred.promise;
}

function requestSomeLink(url) {
    var deferred = q.defer();
    request(url, function(err, resp, body) {
            if (err || resp.statusCode !== 200) {
                deferred.reject(new Error(resp.statusCode + ' ' + err + ' ' + body));
            } else {
                $ = cheerio.load(body);
                deferred.resolve(body);
            }
        });
    return deferred.promise;
}

The code now generates an array of promises to request each URL 代码现在生成一个promises数组来请求每个URL

Actually it's an array of function which would each yield a promise for an url request when called. 实际上它是一个函数数组,每个函数都会在调用时产生对url请求的承诺。 I think you should simply make it an array of links (strings), nothing more - what happens with them is to be determined in another function. 我认为你应该简单地使它成为一个链接(字符串)数组,仅此而已 - 它们发生的事情是在另一个函数中确定。 So 所以

function requestLinksFromRss(url) {
    …
                    if (match)
                        someLinks.push(match[1]);
    …
    return deferred.promise;
}

Perhaps I need to use Q.all() but that seems to be for predetermined functions? 也许我需要使用Q.all(),但这似乎是预定的功能?

I don't see what you mean by "predetermined functions". 我没有看到“预定功能”的含义。 Q.all() just takes an array of promises as its argument. Q.all()只是将一组promise作为其参数。 That's what we have here. 这就是我们在这里所拥有的。

requestLinksFromRss(rssSourceUrl).then(function(links) { 
    var promiseArr = links.map(requestSomeLink); // or a loop if you want
    return Q.all(promiseArr);
}).then(function(ressources) {
    // now you have an array of request bodies.
    // Do something with them.
}).catch(console.log.bind(console)).done();

You are not generating an "array of promises", but an array of functions that will ultimately return a promise. 您没有生成“承诺数组”,而是最终会返回承诺的一系列函数。 Where do you call those functions? 你在哪里称这些功能?

Let's say you go back to returning an array of links, and still have your requestSomeLink(url) function. 假设您返回返回一系列链接,并且仍然具有您的requestSomeLink(url)功能。

requestRss(rssSourceUrl)
.then(function(links) { 
    var index;
    for (index = 0; index < links.length; index++) {
        requestSomeLink(links[index]).then(function(data) {
            // do something with data
        }
    }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM