Можете ли вы возвращать разные значения каждый раз, когда вызываете функцию? - JavaScript - PullRequest
2 голосов
/ 12 ноября 2019

У меня есть функция ниже, цель которой состоит в том, чтобы просмотреть локальный каталог с изображениями и автоматически опубликовать его в твиттере. Я не хочу, чтобы фотографии загружались повторно, если они были загружены ранее.

   function random_from_array(images){
     return images[Math.floor(Math.random() * images.length)];
   }

Функция, которая использует функцию random_from_array.

function upload_random_image(images){
  console.log('Opening an image...');
  var image_path = path.join(__dirname, '/images/' + random_from_array(images)),
      b64content = fs.readFileSync(image_path, { encoding: 'base64' });

  console.log('Uploading an image...');

  T.post('media/upload', { media_data: b64content }, function (err, data, response) {
    if (err){
      console.log('ERROR:');
      console.log(err);
    }
    else{
      console.log('Image uploaded!');
      console.log('Now tweeting it...');

      T.post('statuses/update', {
        media_ids: new Array(data.media_id_string)
      },
        function(err, data, response) {
          if (err){
            console.log('ERROR:');
            console.log(err);
          }
          else{
            console.log('Posted an image!');
          }
        }
      );
    }
  });
}

На данный момент она просто выбирает случайное число из параметра массива, который передается, однако я былинтересно, есть ли способ, чтобы каждый раз, когда он вызывался, он мог возвращаться таким способом ниже. Всякий раз, когда я пытаюсь выполнить цикл и возвращать каждую итерацию, она дает мне только первую итерацию, предположительно потому, что возврат прекращается.

   return images[0]  
   return images[1] //Next Invocation
   return images[2] //Next Invocation...

Я следую этому уроку https://botwiki.org/resource/tutorial/random-image-tweet/#posting-images

Спасибозаранее за любую помощь, я застрял.

1 Ответ

1 голос
/ 12 ноября 2019

Если вы можете изменить структуру вызывающего кода, попробуйте вместо этого использовать функцию более высокого порядка: один раз вызвать массив images, который возвращает функцию, которая при вызове возвращает следующий элемент в массиве:

const makeIterFn = images => () => images.unshift();

А затем назовите его следующим образом:

const iterFn = makeIterFn(arrOfImages);
iterFn(); // first item in array
iterFn(); // second item in array

Если вы хотите избежать изменения аргумента, slice сначала:

const makeIterFn = (images) => {
  const imagesCopy = images.slice();
  return () => imagesCopy.unshift();
};

Вы также можете использоватьвстроенный итератор массива - вместо random_from_array вызовите массив Symbol.iterator, чтобы получить для него итератор, а затем вызовите его метод next(), чтобы получить следующий элемент в массиве:

const iterator = arrOfImages[Symbol.iterator]();
iterator.next().value // first image
iterator.next().value // second image

Если это делается в цикле, возможно, было бы более разумно использовать for (const image of arrOfImages) {, если это возможно, но недостаточно контекста, чтобы сказать наверняка.

...