2015-04-29 23 views
3

我想改變的功能,使用無極應對回調無極未定義

混帳的結果是這樣的

[{ 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與局域網' } ] 

在第一時間,我使用該模塊「Q」改變功能

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; 

     }); 

} 

我希望我可以「那麼」

得到的結果

但我失敗:

TypeError: Cannot read property 'then' of undefined 

和我嘗試這樣:

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; 

    }); 

} 

,但它並沒有像以前那樣工作..

TypeError: Promise resolver undefined is not a function 

我改變了像這樣的功能,它的工作:

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; 

} 

,我想要得到的結果是:

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

我不知道爲什麼數據是[]?

實際上,這是我第一次使用的承諾,我很困惑,如何使用承諾更改功能,請幫助我,非常感謝〜

回答

3

你的第三種方法是好的,但是當你在返回承諾之前「解決」延期時你錯了。您應該在異步代碼中使其成爲同步解析。因此,解決辦法其實是你的#1 try和#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; 
} 
+1

PS:遞延用於轉換異步代碼爲承諾。因此,該方法必須返回promise對象,該對象將在其後包含的異步代碼片段中「稍後」解析。 – Joel

+0

非常感謝〜 – qianjiahao

+0

@Joel或@qianjahao你能解釋爲什麼前兩種方法不正確嗎?傳遞一個承諾,以後使用'then'解決它是錯誤的嗎? –

1

你需要return你在年底創造的承諾你的兩個功能。

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

看來你試圖從回調中返回它。它需要立即返回(以便可以添加處理程序)。

+0

謝謝你幫〜 – qianjiahao