Promise undefined

I want to change the function to use a Promise to handle the callback

the fatch result looks like this:

[{ href: 'http:/segmentfault.com/q/1010000002714413',
    title: 'js图片轮播' },
  { href: 'http:/segmentfault.com/q/1010000002714953',
    title: 'stackoverflow, segmentfault 之类的网站是如何实现在输入问题时,下方出现模糊搜索的结果提示?' },
  { href: 'http:/segmentfault.com/q/1010000002711687',
    title: 'js与局域网' } ]

      

the first time i use the "q" module to change the function

function fatch(url) {

    var deferred = Q.defer();
    superagent.get(url)
        .end(function(err, data) {
            if (err){
                console.log(err);
                deferred.reject(err);
            } 
            var $ = cheerio.load(data.text);
            var result = [];

            $('.question-stream .stream-list__item').each(function(index, ele) {
                var $ele = $(ele);
                var href = path.join(url, $ele.find('.title a').attr('href'));
                var title = $ele.find('.title').text();

                result.push({
                    href: href,
                    title: title
                });
            });

            // console.log(result);
            deferred.resolve(result)
            return deferred.promise;

        });

}

      

I was expecting that I would get the result "then"

fatch(url).then(console.log(data),console.log(err));

      

but i am failing:

TypeError: Cannot read property 'then' of undefined

      

and i try like this:

function fatch(url) {

var promise = new Promise();
superagent.get(url)
    .end(function(err, data) {
        if (err){
            console.log(err);
            promise.reject(err);
        } 
        var $ = cheerio.load(data.text);
        var result = [];

        $('.question-stream .stream-list__item').each(function(index, ele) {
            var $ele = $(ele);
            var href = path.join(url, $ele.find('.title a').attr('href'));
            var title = $ele.find('.title').text();

            result.push({
                href: href,
                title: title
            });
        });

        // console.log(result);
        promise.resolve(result)
        return promise;

    });

}

      

but it didn't work like it used to ..

TypeError: Promise resolver undefined is not a function

      

i changed this function as follows:

function fatch(url) {

    var deferred = Q.defer();
    var result = [];
    superagent.get(url)
        .end(function(err, data) {
            if (err) {
                console.log(err);
            }
            var $ = cheerio.load(data.text);


            $('.question-stream .stream-list__item').each(function(index, ele) {
                var $ele = $(ele);
                var href = path.join(url, $ele.find('.title a').attr('href'));
                var title = $ele.find('.title').text();

                result.push({
                    href: href,
                    title: title
                });
            });

        });
    // console.log(result);
    deferred.resolve(result);

    return deferred.promise;

}

      

and I want to get the result:

fatch(url).then(function(data){
    console.log(data);
},function(err){
    console.log(err);
});

      

I don't know why the data is []?

Actually, this is my first time to use Promise and I am confused how to use Promise to change function, please help me and thanks a lot ~

+3


source to share


2 answers


Your third approach is good, but you are wrong when you "resolve" deferred before returning the promise. You resolve it synchronously while you have to do it in your asynchronous code. So the solution is actually a combination between attempt # 1 and # 3:



function fatch(url) {

    var deferred = Q.defer();
    superagent.get(url)
        .end(function(err, data) {
            if (err){
                console.log(err);
                deferred.reject(err);
            } 
            var $ = cheerio.load(data.text);
            var result = [];

            $('.question-stream .stream-list__item').each(function(index, ele) {
                var $ele = $(ele);
                var href = path.join(url, $ele.find('.title a').attr('href'));
                var title = $ele.find('.title').text();

                result.push({
                    href: href,
                    title: title
                });
            });

            // console.log(result);
            deferred.resolve(result);

        });

    return deferred.promise;
}

      

+3


source


You need a return

promise that you create at the end of your two functions.

function fetch(url) {
    var deferred = Q.defer();
    // ...
    return deferred.promise;
}

      



You seem to be trying to return it from the callback. It must be returned immediately (so handlers can be added).

+1


source







All Articles