简体   繁体   English

node.js承诺不强制执行功能

[英]node.js promises not forcing order execution of functions

I have three functions that I want to use promises to force them to execute in order. 我想使用promise来强制它们按顺序执行的三个功能。

function 1 sends a http request, fetches JSON data and saved it to a file function 2 loops through that file and updates the database according the difference values/values missing function 3 will loop through the newly updated database and create a 2nd json file. 函数1发送一个http请求,获取JSON数据并将其保存到文件中。函数2遍历该文件并根据差异值/值缺失更新数据库。函数3遍历新近更新的数据库并创建一个第二个json文件。

Currently function 1 works perfectly on its own with a setInterval of 30 minutes. 当前,函数1的setInterval为30分钟,可以完美地独立工作。

I want to start function 2 when function 1 has finished. 我想在功能1完成后启动功能2。 then function 3 after function 2 has finished. 功能2完成后,再执行功能3。

Using promises I am trying to attach function 2 to a simple finished log to understand how to use promises but not getting much success. 使用诺言我正在尝试将函数2附加到一个简单的完成日志中,以了解如何使用诺言但不会获得太大的成功。 The items from the for loop log but my Finished/err log before my for loop which shouldn't be happening. for循环日志中的项目,但是我的for循环之前的Finished / err日志不应该发生。 Any suggestions? 有什么建议么?

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

Promises have no magical powers. 承诺没有神奇的力量。 They don't magically know when async code inside them is done. 他们不知道内部代码何时完成。 If you create a promise, you yourself have to resolve() or reject() it when the async code has an error or completes. 如果创建承诺,则异步代码有错误或完成时,您必须自己resolve()reject()

Then, in addition, you have to pass a function reference to a .then() handler, not the result of executing a function. 然后,此外,您必须将函数引用传递给.then()处理函数,而不是执行函数的结果。 .then(fin()) will call fin() immediately and pass it's return value to .then() which is not what you want. .then(fin())将立即调用fin()并将其返回值传递给您不需要的.then() You want something like .then(fin) . 您想要.then(fin)类的东西。

Here's how you can resolve and reject the promise you created: 您可以通过以下方式解决和拒绝所创建的承诺:

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

And, you could use that like this: 而且,您可以这样使用:

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

Summary of changes: 变更摘要:

  1. Added resolve, reject arguments to Promise callback so we can use them 添加了resolve,拒绝Promise回调参数,以便我们可以使用它们
  2. Called reject(err) when there's an error 发生错误时称为reject(err)
  3. Called resolve() when the async code is done. 异步代码完成后称为resolve()
  4. Passed a function reference for both .then() handlers. 为两个.then()处理函数传递了一个函数引用。

FYI, when creating a promise wrapper around an async function, it is generally better to wrapper just the function itself. 仅供参考,在围绕异步函数创建Promise包装器时,通常最好仅包装函数本身。 This makes the wrapper 100% reusable and puts more of your code in the promise architecture which generally streamlines things and makes error handling easier. 这样可以使包装程序100%可重用,并将更多代码放入Promise体系结构中,这通常可以简化事情并简化错误处理。 You could fix things up that way like this: 您可以这样解决问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM