如何正确实现.then承诺

时间:2017-11-03 01:19:08

标签: javascript jquery promise

我怎么能实现一个.then承诺,所以一旦这个函数运行,我在数组里面有什么东西?

我可以将console.log结果导入到函数中,我相信它会正确返回结果,但res.json结果将显示一个空数组。我假设是因为它比函数完成加载更快。



const {grabArticles} = require('../controller/update.js');

// variables
const router = express.Router();


router.get('/new', (err, res) => {
  const results = [];
  const test = grabArticles(results)
  test.then((results) => {
    res.json(results);
  })
});






//different file
const request = require('request');
const cheerio = require('cheerio');

grabArticles = (results) => {
  // const results = [];
  request("https://fivethirtyeight.com/", function(error, response, html) {
    const $ = cheerio.load(html);
    for (x=1; x<4; x++) {
      // i is the current loop number, element=this is the current data requested
      $('#home-feature-' + x.toString()).each((i, element) => {
        const topic = $(element).children('.post-info').children('.topic').text().trim();
        const title = $(element).children('.post-info').children('.tease-meta').children('.tease-meta-content').children('h2.article-title.entry-title').text().trim();
        // console.log('topic: ' + topic + '\n' + 'title: ' + title);
        const newArticle = {
          topic: topic,
          title: title
        };
        results.push(newArticle);
      })
    }
    console.log('inside update.js' + results);
  });
  return results;
}
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

您需要返回Promise,然后解析results。然后results的值将作为第一个参数传递给您当时的回调。

未经测试但看起来像这样:

&#13;
&#13;
//different file
const request = require('request');
const cheerio = require('cheerio');

grabArticles = (results) => {
  // const results = [];
  return new Promise(function(resolve) {
    request("https://fivethirtyeight.com/", function(error, response, html) {
      const $ = cheerio.load(html);
      for (x = 1; x < 4; x++) {
        // i is the current loop number, element=this is the current data requested
        $('#home-feature-' + x.toString()).each((i, element) => {
          const topic = $(element).children('.post-info').children('.topic').text().trim();
          const title = $(element).children('.post-info').children('.tease-meta').children('.tease-meta-content').children('h2.article-title.entry-title').text().trim();
          // console.log('topic: ' + topic + '\n' + 'title: ' + title);
          const newArticle = {
            topic: topic,
            title: title
          };
          results.push(newArticle);
        })
      }
      console.log('inside update.js' + results);
      
      //////////////////////////
      /// Resolve the promise here
      /// the then() will get triggered
      //////////////////////////
      resolve(results);
    });
  });
}
&#13;
&#13;
&#13;

非常简化的版本如下所示:

// This function returns a Promise
function doSomethingAysnc(){
    return new Promise(function(resolve){
        request('/my/url', function(data){
            // When we are staisfied with ending the promise
            // We resolve it so the calling function can then 
            // handle the rest
            return resolve(data);
        });
    });
}

// Here we will call our async function
// Once the promise resolves
// We get our data back for further usage
doSomethingAysnc().then(function(data){
    // We can the access the data here
    console.log(data);
});

答案 1 :(得分:0)

使用像这样的Promise重写你的grabArticles。

grabArticles = (results) => {
  return new Promise((resolve, reject) => {
    request("https://fivethirtyeight.com/", function(error, response, html) {
      const $ = cheerio.load(html);
      for (x=1; x<4; x++) {
        // i is the current loop number, element=this is the current data requested
        $('#home-feature-' + x.toString()).each((i, element) => {
          const topic = $(element).children('.post-info').children('.topic').text().trim();
          const title = $(element).children('.post-info').children('.tease-meta').children('.tease-meta-content').children('h2.article-title.entry-title').text().trim();
          // console.log('topic: ' + topic + '\n' + 'title: ' + title);
          const newArticle = {
            topic: topic,
            title: title
          };
          results.push(newArticle);
        })
      }
      console.log('inside update.js' + results);
      // return result using resolve, otherwise using reject(error) to reflect something wrong
      resolve(results);
    });
  });
}