暂停一段时间的程序

我正在写一个基本上完成以下任务的程序。

  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秒,然后继续,直到下一次100logging等…输出应该是喜欢

 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在callback函数中给出索引

 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); } }); 

我可以做的是沟通使用forEach ,而是使用自调用函数遍历列表,并在必要时应用超时。

 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) 

我的理解一直是,你不能简单地只是“暂停”Javascript。 当setTimeout被触发的时候,你的函数的其余部分将会继续运行,因为它是asynchronous的。 这将需要3秒的时间才能在你的控制台中显示“blah blah blah” – 它不会保持你的应用程序。


编辑#1

在JavaScript中实现“暂停”的唯一方法是创build一个需要3秒钟(或者需要很长时间)才能完成的function。 虽然这不是最好的做法,因为它有效地locking了你的页面…下面的代码将做你想要的 – 一个满足特定条件的三秒延迟。

 <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整除的数字,它就会locking执行3秒钟,然后继续到数组中的其他数字。

1,2,3 …(3秒)… 4,5,6 …(3秒)… 7,8,9(3秒)…

从我所知道的和已经读过的,这是真正实现JavaScript的唯一方法。 我会提供一个额外的资源,以供您阅读。

资源: JavaScript中是否有睡眠function?


编辑#2

这是你的工作与我提到的function上面提到的用于暂停你的function3秒,当你的条件满足…

 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); }