暂停程序一段时间

时间:2017-10-26 20:20:19

标签: javascript node.js settimeout

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

  1. 阅读json文件。
  2. 将项目从文件插入DynamoDB
  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) {
            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++;
    });
    

    基本上,我正在尝试,运行程序并将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
    

    这很令人困惑,请让我知道我哪里出错了,我该如何解决这个问题。

    由于

3 个答案:

答案 0 :(得分: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);
 }
});

答案 1 :(得分:0)

我可能会做的是使用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)

答案 2 :(得分:0)

我的理解一直是你不能简单地只是暂停"的JavaScript。当触发setTimeout时,你的其余功能会立即继续运行,因为它是异步的...... 它会花费3秒钟来等待#34; blah blah blah"在您的控制台中显示 - 它不会保留您的应用程序。

编辑#1

完成"暂停"的唯一方法在JavaScript中创建一个需要3秒钟(或者你想要它需要多长时间)才能完成的函数。虽然这不是最好的做法,因为它有效地锁定了您的页面...以下代码将按照您的需要执行 - 在满足某个条件时延迟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中实现此目的的唯一方法。我还会为您提供额外的资源。

资源:Is There a Sleep Function in 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);
}