javascript - setInterval 中的 Promise

标签 javascript node.js mongodb promise setinterval

我有一个 setInterval 每秒运行一个 promise,在每个 promise 的 then 函数中,我将输出放入 MongoDB 数据库(尽管由于某种原因它不工作)。

我想在一切都完成后关闭与数据库的连接,但我不知道如何让连接的关闭仅在所有 promise 都完成并且一切都已完成写入数据库时​​运行。

这是我当前的代码:

我有一个 client.js 文件,用于向商店发出查询,使用 promise ,还有一个 db.js,用于处理数据库功能。

客户端.js

var id = setInterval(function(){

        if (i == (categories.length-1))
            clearInterval(id);


            var category = categories[i];

            client.itemSearch({  
              searchIndex: SearchIndex,
              categoryID: category.id,
              keywords: currentKeyword
            })
            .then(function(results){

                var title = results[0].Title;
                var cat = category.name;
                var price = results[0].Price

                db.insertProduct(title,cat,price).then(function(){
                    console.log("Added " + title);
                })
            },function(err) {
                console.log("error at " + category.name);
            });
            i+=1;
    }, 1000)

queryStore();

db.js

var mongoose = require("mongoose");

mongoose.connect('mongodb://localhost:27017/catalog');

var schema = new mongoose.Schema({
    title           : String,
    category        : String,
    price           : Number,
}, {collection: "catalog"});

var Product = mongoose.model("Product", schema);

Product.remove({}, function() {
    console.log('Database cleared.') 
});


exports.clearDB = function() {
    Product.remove({});
}

exports.insertProduct = function (Title,Category,Price) {
    var entry = new Product({
        title: Title,
        category: Category,
        price: Price,
    });

    entry.save();
}

exports.closeConn = function() {
    console.log("Closing DB Connection");
    mongoose.connect().close();
}

此外,由于我对 JavaScript 和 Node.js 完全陌生,任何最佳实践或一般提示都将不胜感激! :)

最佳答案

正如所写,您依靠 1 秒的时间间隔在搜索/插入序列的连续调用之间施加延迟。这并没有什么根本性的错误,但是它不能保证每一步都在下一步开始之前完成,也不能保证下一步会尽快开始。在每一步,1 秒的延迟可能绰绰有余或不够,你真的不知道。

幸运的是,promises 提供了一种更好的方法来应对异步。

从一个数组开始,一个经过良好尝试的 reduce 模式是可用的(参见“The Collection Kerfuffle”here 强加一个序列:

array.reduce(function(promise, item) {
    return promise.then(function() {
        return doSomethingAsync(item);
    });
}, Promise.resolve());

其中 Promise 是 ES6 的原生 Promise,或者例如 Bluebird。

对于问题中的代码,doSomethingAsync() 部分扩展为:

categories.reduce(function(promise, category) {
    return promise.then(function() {
        return client.itemSearch({
            'searchIndex': SearchIndex,
            'categoryID': category.id,
            'keywords': currentKeyword
        }).then(function(results) {
            var title = results[0].Title;
            var cat = category.name;
            var price = results[0].Price;
            return db.insertProduct(title, cat, price);
        }).then(function() {
            console.log("Added " + title);
        }).catch(function(err) {
            console.log("error at " + category.name);
        });
    });
}, Promise.resolve());

整个缩减过程返回一个 promise ,它本身可以返回和/或与其他 promise 聚合。

关于javascript - setInterval 中的 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34754767/

相关文章:

javascript - 将基于数据的格式添加到 FullCalendar jquery 插件事件

node.js - 简单的 hello-world 应用程序在加载 800 个并发请求时速度很慢(130+ms)

javascript - 为什么我的类构造变量在声明后保持未定义状态?

javascript - 类型错误 : todo is not a function

java - Ajax 使用 Javascript 调用同一 JSP

javascript - 如何更改网站背景

用于计算参数值的 MapReduce

javascript - 404 错误, 'get' 从本地托管服务器获取请求

java - HTMLUnit 等待 JS 问题

node.js - mongodb 聚合更新集合