Приостановить программу на некоторое время

1

Я пишу программу, которая в основном выполняет следующие задачи.

  1. Прочтите json файл.
  2. Вставьте элемент из файла в DynamoDB

Ниже мой код.

const AWS = require('aws-sdk');
var fs = require('fs');
var docClient = new AWS.DynamoDB.DocumentClient();

var i = 0;

var allMovies = JSON.parse(fs.readFileSync('JsonFiles/Cars.json', 'utf8'));
allMovies.forEach(function (user) {
    var params = {
        TableName: "CarsData",

        Item: {
            "id": user.id,
            "make": user.Make.toLowerCase(),
            "model": user.Model.toLowerCase(),
            "year": user.Year,
        }
    };
    if (i % 100 == 0) {
        setTimeout(function () {
            console.log('Blah blah blah blah extra-blah');
        }, 3000);
    }
    docClient.put(params, function (err, data) {
        if (err) {
            console.error("Unable to add user", user.Region, ". Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log('PutItem succeeded: ', i);
        }
    });
    i++;
});

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

put item succeeded: 3825
...99 more records....
Blah blah blah blah extra-blah
----------wait for 3 seconds-----
put item succeeded: 3825
...99 more records....
Blah blah blah blah extra-blah
----------wait for 3 seconds-----
.........and so on till the entire data is inserted

Когда я запускаю приведенный выше код, вывод, который я получаю, приведен ниже.

Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
Blah blah blah blah extra-blah
PutItem succeeded:  3825
PutItem succeeded:  3825

Это довольно запутанно, сообщите мне, где я ошибаюсь и как я могу это исправить.

Спасибо

  • 1
    Я думаю, вам нужно добавить, почему вы пытаетесь это сделать. Правильный ответ на этот вопрос зависит от «почему». Если вы пытаетесь дождаться выполнения определенной задачи и думаете, что подождет произвольное количество времени, вам стоит взглянуть на Обещания. Если вы просто пытаетесь настроить консоль для пользователя, чтобы убедиться, что он видит сообщение журнала, другое решение будет более подходящим. Пожалуйста, дайте больше деталей.
Теги:
settimeout

3 ответа

1
Лучший ответ

Вы можете попробовать это. forEach дает индекс в функции обратного вызова

const AWS = require('aws-sdk');
var fs = require('fs');
var docClient = new AWS.DynamoDB.DocumentClient();

var allMovies = JSON.parse(fs.readFileSync('JsonFiles/Cars.json', 'utf8'));
allMovies.forEach(function (user, index) {
    var params = {
        TableName: "CarsData",

        Item: {
            "id": user.id,
            "make": user.Make.toLowerCase(),
            "model": user.Model.toLowerCase(),
            "year": user.Year,
        }
    };
    if ((index + 1) % 100 == 0) { // since index starts with 0;
        setTimeout(function () {
            console.log('Blah blah blah blah extra-blah');
        }, 3000);
    }
    docClient.put(params, function (err, data) {
        if (err) {
            console.error("Unable to add user", user.Region, ". Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log('PutItem succeeded: ', i);
        }
    });
});

Очень простой пример использования javascript

var arr = [1,2,3,4];
arr.forEach(function(x, index) {
console.log(x);
if(index == 3) {
    window.setTimeout(function(){ console.log('Im timeout blah blan'); }, 1000);
 }
});
0

Мое понимание всегда заключалось в том, что вы просто не можете просто "приостановить" Javascript. Когда запускается setTimeout, остальная часть вашей функции будет продолжать работать сразу же после ее асинхронности... для отображения "бла-бла-бла" на консоль потребуется 3 секунды - она не будет удерживать ваше приложение.


Редактировать # 1

Единственный способ выполнить "паузу" в JavaScript - это создать функцию, для завершения которой требуется 3 секунды (или сколько угодно времени). Хотя это не самая лучшая практика, поскольку она эффективно блокирует вашу страницу... следующий код будет делать то, что вам нужно, - трехсекундная задержка при выполнении определенного условия.

<script>
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
arr.forEach(function (x) {
    console.log(x)
    if (x % 3 == 0) {
        console.log("blah blah blah");
        sleep(3000)
    }
});

function sleep(delay) {
    var start = new Date().getTime();
    while (new Date().getTime() < start + delay);
}
</script>

Таким образом, всякий раз, когда появляется число, делящееся на 3, оно блокирует выполнение в течение 3 секунд, а затем переходит к дополнительным номерам в массиве.

1, 2, 3... (3 секунды)... 4, 5, 6... (3 секунды)... 7, 8, 9 (3 секунды)...

Из того, что я знаю и прочитал, это действительно единственный способ добиться этого в JavaScript. Я также предоставил вам дополнительный ресурс для чтения.

Ресурс: есть ли функция сна в JavaScript?


Редактировать # 2

Вот ваша работа с предлагаемой функцией, о которой я говорил выше, используется для приостановки вашей функции в течение 3 секунд, когда ваше условие выполняется...

const AWS = require('aws-sdk');
var fs = require('fs');
var docClient = new AWS.DynamoDB.DocumentClient();

var i = 0;

var allMovies = JSON.parse(fs.readFileSync('JsonFiles/Cars.json', 'utf8'));
allMovies.forEach(function (user) {
    var params = {
        TableName: "CarsData",

        Item: {
            "id": user.id,
            "make": user.Make.toLowerCase(),
            "model": user.Model.toLowerCase(),
            "year": user.Year,
        }
    };
    if (i % 100 == 0) {
         console.log('Blah blah blah blah extra-blah');
         sleep(3000);
    }
    docClient.put(params, function (err, data) {
        if (err) {
            console.error("Unable to add user", user.Region, ". Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log('PutItem succeeded: ', i);
        }
    });
    i++;
});

function sleep(delay) {
    var start = new Date().getTime();
    while (new Date().getTime() < start + delay);
}
0

То, что я могу сделать, это использовать канаву forEach и вместо этого использовать функцию self-invocation для итерации по списку и применения тайм-аута, когда это необходимо.

var cooldownIteration = function(array, index) {
  if (index >= array.length) {
    return; //Make sure we dont try to access non-existing indexes
  }
  var user = array[index];

  var params = {
    TableName: "CarsData",

    Item: {
      "id": user.id,
      "make": user.Make.toLowerCase(),
      "model": user.Model.toLowerCase(),
      "year": user.Year,
    }
  };

  index++ // Use the next index for the next time the function is ran

  docClient.put(params, function(err, data) {
    if (err) {
      console.error("Unable to add user", user.Region, ". Error JSON:", JSON.stringify(err, null, 2));
    } else {
      console.log('PutItem succeeded: ', i);
    }

    //Assuming docClient.put is asynchronous then you should call the next cycle inside of the put as you dont want another cycle to start before one ends
    if (index % 100 == 0) {
      setTimeout(cooldownIteration(array, index), 3000) //Once the operations are done and the index is a multiple of 100 then call the same function again with the increased index 3 seconds later
    } else {
      cooldownIteration(array, index) // If the index is not a multiple of 100 then call the function without delay.
    }
  });
}

var allMovies = JSON.parse(fs.readFileSync('JsonFiles/Cars.json', 'utf8'))
cooldownIteration(allMovies, 0)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню