Я пишу программу, которая в основном выполняет следующие задачи.
Ниже мой код.
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
Это довольно запутанно, сообщите мне, где я ошибаюсь и как я могу это исправить.
Спасибо
Вы можете попробовать это. 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);
}
});
Мое понимание всегда заключалось в том, что вы просто не можете просто "приостановить" 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);
}
То, что я могу сделать, это использовать канаву 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)