【问题标题】:node.js promises not forcing order execution of functionsnode.js 承诺不强制按顺序执行函数
【发布时间】:2016-08-25 18:47:05
【问题描述】:

我想使用三个函数来强制它们按顺序执行。

函数 1 发送一个 http 请求,获取 JSON 数据并将其保存到一个文件中 函数 2 循环遍历该文件并根据缺失的差异值/值更新数据库 函数 3 将遍历新更新的数据库并创建第二个 json 文件。

目前,函数 1 可以自行完美运行,setInterval 为 30 分钟。

我想在功能 1 完成后启动功能 2。然后函数 2 完成后函数 3。

使用 Promise 我试图将函数 2 附加到一个简单的已完成日志中,以了解如何使用 Promise,但没有取得多大成功。 for 循环日志中的项目,但我的 for 循环之前的 Finished/err 日志不应该发生。有什么建议吗?

function readJson() {
    return new Promise(function() {
        fs.readFile(__dirname + "/" + "bitSkin.json", 'utf8', function read(err, data) {
            if (err) { throw err; }
            var bitCon = JSON.parse(data);  

            for(var i=0; i<7; i++) { //bitCon.prices.length; i++) {
                var price = bitCon.prices[i].price
                var itemName = bitCon.prices[i].market_hash_name;
                (function() {
                    var iNameCopy = itemName;
                    var priceCopy = price;
                    logger.info(iNameCopy);
                }());
            }
        });
    });
};

function fin() {
    logger.info("Finished");
}

readJson().then(fin(), console.log("err"));

【问题讨论】:

    标签: javascript node.js promise


    【解决方案1】:

    承诺没有神奇的力量。他们并不神奇地知道其中的异步代码何时完成。如果你创建了一个 Promise,当异步代码出错或完成时,你必须自己 resolve() 或 reject() 它。

    然后,此外,您必须将函数引用传递给.then() 处理程序,而不是执行函数的结果。 .then(fin()) 将立即调用 fin() 并将其返回值传递给 .then() 这不是您想要的。你想要.then(fin)之类的东西。

    您可以通过以下方式解决和拒绝您创建的承诺:

    function readJson() {
        return new Promise(function(resolve, reject) {
            fs.readFile(__dirname + "/" + "bitSkin.json", 'utf8', function read(err, data) {
                if (err) { return reject(err); }
                var bitCon = JSON.parse(data);  
    
                for(var i=0; i<7; i++) { //bitCon.prices.length; i++) {
                    var price = bitCon.prices[i].price
                    var itemName = bitCon.prices[i].market_hash_name;
                    (function() {
                        var iNameCopy = itemName;
                        var priceCopy = price;
                        logger.info(iNameCopy);
                    }());
                }
                resolve(bitCon);
            });
        });
    };
    

    而且,你可以这样使用:

    function fin() {
        logger.info("Finished");
    }
    readJson().then(fin, function(err) {
        console.log("err", err)
    });
    

    变更摘要:

    1. 为 Promise 回调添加了 resolve、reject 参数,以便我们可以使用它们
    2. 出现错误时调用reject(err)
    3. 异步代码完成后调用resolve()。
    4. 为两个 .then() 处理程序传递了一个函数引用。

    仅供参考,当围绕异步函数创建承诺包装器时,通常最好只包装函数本身。这使得包装器 100% 可重用,并将更多代码放入 Promise 架构中,这通常会简化事情并使错误处理更容易。你可以这样解决问题:

    fs.readFilePromise = function(file, options) {
        return new Promise(function(resolve, reject) {
            fs.readFile(file, options, function(err, data) {
                if (err) return reject(err);
                resolve(data);
            });
        });
    });
    
    function readJson() {
        return fs.readFilePromise(__dirname + "/" + "bitSkin.json", 'utf8').then(function(data) {
            var bitCon = JSON.parse(data);
            bitCon.prices.forEach(function(item) {
                logger.info(item.market_hash_name);
            });
            return bitCon;
        });
    }
    

    【讨论】:

    猜你喜欢
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2022-12-11
    • 2017-12-08
    相关资源
    最近更新 更多