2015-04-29 3 views
3

я хочу, чтобы изменить функцию для использования Promise, чтобы иметь дело с обратным вызовомPromise не определено

результат fatch подобно этому

[{ 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与局域网' } ] 

в первый раз, я использую модуль «д» для изменения функции

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; 

     }); 

} 

я ожидал, что я могу получить результат на «потом»

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

но я не в состоянии:

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 и # попробуй 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: отсроченной используются для преобразования асинхронизированного кода в обещание. Таким образом, метод должен возвращать объект обещания, который будет разрешен «позже», в асинхронизированных фрагментах кода, который он содержит. – Joel

+0

большое спасибо ~ – qianjiahao

+0

@Joel или @qianjahao вы можете объяснить, почему первые два подхода неверны? Неправильно ли передавать обещание, которое нужно разрешить, используя 'then' позже? –

1

Вы должны return обещания вы создаете в конце ваши две функции.

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

Кажется, вы пытаетесь вернуть его изнутри обратного вызова. Он должен быть немедленно возвращен (чтобы можно было добавить обработчики).

+0

спасибо за помощь ~ – qianjiahao

Смежные вопросы