简体   繁体   中英

NodeJS returned data sometimes changes

I'm new to NodeJS and I have a problem I don't understand.

In this function, I call several API one after another to retrieve some data about a movie. The result isn't always the same. Most of the time, the result is correct, but sometimes the result isn't complete.

I tried using then to try and chain the API calls but it doesn't seem to work.

Any idea why the result isn't always the same? Any help would be appreciated.

// test fetchData(456165)

function fetchData(filmid) {

let average = array => array.reduce((a, b) => a + b) / array.length
var notes = []

mdb.movieInfo({
    id: filmid,
    language: 'fr'
  },
  (err, resOmdb) => {
    notes.push(parseFloat(resOmdb.vote_average))
    imdb
      .getById(resOmdb.imdb_id, {
        apiKey: 'e9d59b68',
        timeout: 3000
      })
      .then(
        allocine.api(
          'search', {
            q: `${resOmdb.title}`,
            filter: 'movie'
          },
          function(error, resAllo) {
            if (error) {
              return
            }

            allocine.api(
              'movie', {
                code: `${resAllo.feed.movie[0].code}`
              },
              function(error, result) {
                if (error) {
                  return
                }
                notes.push(parseFloat(result.movie.statistics.userRating) * 2)
              }
            )

            // doesn't seem to execute all the time
            allocine.api(
              'showtimelist', {
                zip: 44260,
                movie: resAllo.feed.movie[0].code
              },
              function(error, resultCin) {
                if (error) {
                  return
                }

                // sometimes doesn't appear in the result
                resOmdb.cinemas = resultCin
              }
            )

          }
        )
      )
      .then(
        function(result) {
          notes.push(parseFloat(result.rating))
          resOmdb.vote_average = average(notes).toFixed(2)

          // check the result
          console.log(util.inspect(resOmdb, false, null))
        },
        function(error) {
          return
        }
      )
  }
)
}

First of all you should decide if you want to use Promises or not. If you do, promisify all functions. Next thing you need to do is 'return' your promises if they are used inside a function.

In your case your first imbd api call is not returned probably.

As next thing you should check if your node version supports async await.

Then you can easily do your api calls without any distractions.

'use strict';

const Promise = require('bluebird');
const mdb = Promise.promisfyAll(require('mdb'));
const allocine = Promise.pomisifyAll(require('allocine-api'));

// test fetchData(456165)

async function fetchDate(filmId) {
  const notes = [];
  const resOmdb = await mdb.movieInfoAsync({ id: filmId });
  notes.push(parseFloat(resOmdb.vote_average));

  const imdbResult = await imdb.getByIdAsync(resOmdb.imdb_id, { apiKey: 'e9d59b68', timeout: 3000 });

  const resAllo = await allocine.apiAsync('search', { q: `${resOmdb.title}`, filter: 'movie' });
  // and so on ...
}

UPDATE: To speed up your function you can do requests concurrently. To do so, use Promise.join

  const [imdbResult, allocineResult] = await Promise.join(
    imdb.getByIdAsync(resOmdb.imdb_id, { apiKey: 'e9d59b68', timeout: 3000 }),
    allocine.apiAsync('search', { q: `${resOmdb.title}`, filter: 'movie' });
  );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM