Nodejs:Promise对象无法解析

时间:2016-08-22 03:42:41

标签: javascript node.js

我有以下代码。查看带有注释的2行,其中没有输出任何内容。我无法理解为什么resolve()函数中的init()不会导致then()函数中this.load()的执行。

module.exports = function(url, list){
    var phantom     = require('phantom');
    var Blacklist   = require('../../lib/util/http/blacklist');

    var blacklist = new Blacklist( list );

    this.load = function(){
        console.log('phantom-page:load', url);
        return new Promise(function(resolve, reject){
            init()
                .then(function(page){
                    console.page('open:', url); // This doesn't output
                    page.open(url)
                        .then(function(status){
                            console.log('opened:', url);
                            resolve( page, status );
                        })
                    ;
                })
            ;
        });
    };

    function init(){
        console.log('phantom-page:init', url);
        return new Promise(function(resolve, reject){
            phantom.create()
                .then(function(instance){
                    console.log('phantom-page: page created');
                    return instance.createPage();
                })
                .then(function(page){
                    block( page );
                    resolve( page );
                    console.log( resolve ); // This outputs [Function]
                });
            ;   
        });

    }

    function block(page){
        console.log('phantom-page:block:rawRegExp', blacklist.rawRegExp);
        page.on('onResourceRequested', true, function(requestData, request, raw) {
            var url = requestData['url'];
            console.log('phantom-page:block:resource', url);
            var regRaw = '(/' + raw + '/gi).test("' + url + '")';
            var isBlacklisted = eval(regRaw);
            if (isBlacklisted) {
                console.log('phantom-page:block:abort', url);
                request.abort();
            }
        }, blacklist.rawRegExp);
    }

};

1 个答案:

答案 0 :(得分:1)

您几乎肯定会在block()收到异常,并应添加.catch()

    .then(function(page){
        block( page );
        resolve( page );
        console.log( resolve ); // This outputs [Function]
    }).catch(function(e) { console.log(e) });

您的问题似乎不是为什么这不起作用,而是为什么console.log()解雇并输出[Function]而您的来电者无法解决,即使您只是CALLED resolve()

这是因为你在这里有一个承诺链。 console.log()立即执行,在当前" tick"中执行。但是resolve()不是 - 那将(几乎 - 取决于你使用的Promise库)总是转到下一个刻度。在此期间,这为异常提供了足够的时间。

.catch()(所有承诺链应包括在内)外,还有两件事可以帮到你:

process.on('uncaughtException', function(exception) {
    console.log('uncaughtException', 'error', { message: exception.message, stack: exception.stack });
});

process.on('unhandledRejection', function(reason) {
    console.log('unhandledRejection', 'error', reason);
});

将这些放在脚本开头的某处。无论出了什么问题,无论哪里出错,如果你没有陷入困境,你将会有一个巨大的谜团要解开(就像你在这里做的那样)。这两个陷阱可以帮助您在忘记处理错误情况时进行追踪,并且可以节省您数小时的调试和抓头。