我有三个函数,我想使用promises强制它们按顺序执行。
函数1发送http请求,获取JSON数据并将其保存到文件中 函数2循环遍历该文件,并根据缺少的差值/值更新数据库 函数3将遍历新更新的数据库并创建第二个json文件。
目前,函数1完全独立,setInterval为30分钟。
我想在功能1完成时启动功能2。功能2完成后功能3。
使用promises我试图将函数2附加到一个简单的完成日志,以了解如何使用promises但没有取得多大成功。 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"));
答案 0 :(得分: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)
});
变更摘要:
reject(err)
resolve()
。.then()
处理程序传递了一个函数引用。仅供参考,在围绕异步函数创建promise包装器时,通常最好只包装函数本身。这使得包装器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;
});
}