簡體   English   中英

在回調中調用異步函數

[英]Calling asynchronous function in callback

我在理解異步功能時遇到了一些麻煩。 我已經閱讀了Mixu的Node Book中的章節,但仍然無法繞開它。

基本上,我想請求一個資源(使用node包cheerio ),解析它以獲取有效的URL,並將每個匹配項添加到我的redis set setname

問題在於最后只將第一個匹配項添加到redis集。

function parse(url, setname) 
{
    request(url, function (error, response, body) 
    {
        if (!error && response.statusCode == 200) 
        {
            $ = cheerio.load(body)

            // For every 'a' tag in the body
            $('a').each(function() 
            {
                // Add blog URL to redis if not already there.
                var blog = $(this).attr('href')
                console.log("test [all]: " + blog);

                // filter valid URLs
                var regex = /http:\/\/[^www]*.example.com\//
                var result = blog.match(regex);
                if(result != null) 
                {
                    console.log("test [filtered]: " + result[0]);

                    redis.sismember(setname, result[0], function(err, reply) 
                    {
                        if(!reply) 
                        {
                            redis.sadd(setname, result[0])
                            console.log("Added " + result[0])
                        }
                        redis.quit()    
                    })
                }
            })
        }
    })
}

我非常感謝您提供有關如何重新構造此結構的指針,以便redis.sadd方法可以正確地處理結果。

當前實現的輸出如下:

test [all]: http://test1.example.com/
test [filtered]: http://test1.example.com/
...
Added http://test2.example.com/

因此,它添加了test1.example.com,但未打印“添加的”行,也沒有添加test2.example.com,而是為其打印了“添加的”行。

謝謝!

第一個問題是由redis.sismember()異步引起的:調用其回調時,您已經覆蓋了result變量,因此它將指向它具有的最后一個值,而不是您調用redis.sismember()的值。 redis.sismember()

解決該問題的一種方法是通過將異步函數包裝在閉包中來創建新的作用域變量:

(function(result) {
  redis.sismember(setname, result[0], function(err, reply) {
    ...
  });
})(result);

另一種選擇是創建用作回調的部分函數:

  redis.sismember(setname, result[0], function(result, err, reply) {
    ...
  }.bind(this, result));

我認為第二個問題是由redis.quit()引起的,它在第一個sadd()之后關閉了Redis連接。 您不是在檢查err ,但是如果這樣做,它可能會告訴您更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM