2016-04-30 31 views
2

我有三个功能,我想使用承诺强制他们按顺序执行。node.js承诺不强制命令执行的功能

功能1发送HTTP请求,获取JSON数据,并将其保存到文件 功能通过该文件2个回路并根据该差分值更新数据库/值丢失 功能3将循环通过新近更新的数据库,并创建第二个json文件。

当前函数1以30分钟的setInterval自身完美工作。

我想在功能1结束时启动功能2。然后功能2完成后功能3。

使用承诺我试图附加功能2到一个简单的完成日志,以了解如何使用承诺,但没有获得太大的成功。来自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")); 

回答

4

承诺没有魔力。他们不会奇迹般地知道它们内部的异步代码何时完成。如果您创建承诺,那么当异步代码出现错误或完成时,您自己必须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回调,所以我们可以使用它们
  2. 当出现错误时调用reject(err)
  3. 当异步代码完成时,调用resolve()
  4. 通过了.then()处理程序的函数参考。

仅供参考,围绕创建一个异步功能的诺言包装时,通常最好为包装只是函数本身。这使得包装100%可重用,并将更多的代码放入承诺架构中,这通常简化了事情并使错误处理更加容易。你可以像这样修复东西:

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

只是想说。这样一个辉煌的答案,谢谢。 – Matt

+0

我在想,如果你看看http://stackoverflow.com/questions/36955428/nested-sql-queries-inside-for-loop-node-js-not-working?如果您有任何建议,会很乐意提供建议! – Matt