循环,DNS和Bluebirdjs - 承诺仍然工作asynchronouse

时间:2018-03-17 01:09:58

标签: javascript promise bluebird

我的功能有点问题,应检查具有特定名称的域是否在少数顶级域下可用。当我把这个函数称为whois(" example434");它返回undefined而不是array [" example424.org",...," example424.com"]。如何修改功能来解决这个问题?哪里弄错了?



{{1}}




1 个答案:

答案 0 :(得分:1)

您的主要问题是:

  1. dns.resolve4看起来不会返回一个promise,因为它使用了nodejs回调模式,因为它没有返回一个promise,Promise.map不会等待异步代码完整
  2. 为什么在Promise.resolve中包装Promise.map - 没有意义,因为Promise.map返回一个promise
  3. 功能whois永远不会返回值,因此您获得undefined
  4. typeof domains永远不会是Object,您的意思是object - 即使这不是确定某个版权是否为Array
  5. 的好方法

    您的标题包含以下短语:承诺仍然可以异步 - 好吧,是的,您还期待别的吗?异步代码是异步的,没有什么会改变

    无论如何,您的代码注释了问题:

    function whois(name, domains = '*') {
        // Issue 4
        if (typeof domains == 'Object' && domains.length > 0) {
            var TLD = domains;
        } else {
            var TLD = ['.com', '.net', '.org', '.edu', '.gov', '.biz', '.info', '.mobi', '.me', '.tv', '.info', '.io'];
        }
    
        var available = [];
        // Issue 2
        Promise.resolve(
            Promise.map(TLD, function(domain) {
                // Issue 1
                return dns.resolve4(name + domain, (err, addresses) => {
                    if (!addresses || addresses.length <= 0) {
                        console.log(name + domain);
                        available.push(name + domain);
                    }
                    // possible error: if there's an error (err is not falsey) does that really mean the domain is available?
                });
            })
        ).then(() => {
            console.log(available);
            return available;
        });
        // Issue 3
    }
    

    您希望在下面的代码中宣传dns.resolve4函数const resolve4 =

    我知道bluebirdjs和后来的nodejs内置了promisify方法,但是那些逻辑意味着err拒绝承诺 你可能不想要的。

    此外,您希望针对不同的成功结果采取不同的解决方案,因此,最好通过手工宣传&#34;&#34;因为它是

    使用Array.isArray确定TLD是否为数组

    function whois (name, TLD) {
        // if TLD isn't an array, use the default array
        if (!Array.isArray(TLD)) {
            TLD = ['.com','.net','.org','.edu','.gov', '.biz', '.info', '.mobi', '.me', '.tv', '.info', '.io'];
        }
    
        // prepare the list of full domains to check
        const domains = TLD.map(domain => name + domain);
    
        const resolve4 = domain => new Promise(resolve => {
            dns.resolve4(domain, (err, addresses) => {
                if (addresses && addresses.length) {
                    // domain resolves - so it's not available
                    resolve(false);
                }
                // uncomment the next two lines if you want an error to indicate the domain is NOT available
                //else if (err) {
                //    resolve(false);
                } else {
                    // it's available
                    resolve(domain);
                }
            });
        });
    
        return Promise.map(domains, resolve4)
        // filter for available domains (i.e. return an array of non-falsey results)
        .then(results => results.filter(domain => domain));
    }