我的代码需要一些帮助。我是Node.js的新手,并且遇到很多麻烦。
我正在尝试做什么:
1)使用Amazon产品(ASIN)获取.txt;
2)使用amazon-product-api包获取所有产品;
3)将每个产品保存在.json文件中。
我的代码不起作用。我想我搞砸了这个异步同步的东西 - 帮帮我吧!
var amazon = require('amazon-product-api');
var fs = require('fs');
var client = amazon.createClient({
awsId: "XXX",
awsSecret: "XXX",
awsTag: "888"
});
var array = fs.readFileSync('./test.txt').toString().split('\n');
for (var i = 1; i < array.length; i++) {
var ASIN = array[i];
return client.itemLookup({
domain: 'webservices.amazon.de',
responseGroup: 'Large',
idType: 'ASIN',
itemId: ASIN
})
.then(function(results) {
fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
if (err) {
console.log(err);
} else {
console.log("JSON saved");
}
})
return results;
}).catch(function(err) {
console.log(err);
});
};
...正确的答案是使用async / await与节点中包含的the native fs
promises module。升级到Node.js 10或11(主要云提供商已经支持)并执行以下操作:
const fs = require('fs').promises;
// This must run inside a function marked `async`:
const file = await fs.readFile('filename.txt', 'utf8');
await fs.writeFile('filename.txt', 'test');
不要使用第三方软件包,也不要编写自己的包装器,这是不再需要的。
在节点11.14.0
之前,你仍会得到一个警告,这个功能是实验性的,但是它运行得很好,这是未来的发展方向。自11.14.0
以来,该功能不再具有实验性,并且可以投入生产。
import
instead of require
?它也有效 - 但仅限于此功能未标记为实验的Node.js版本。
import { promises as fs } from 'fs';
(async () => {
await fs.writeFile('./test.txt', 'test', 'utf8');
})();
因为fs.writefile
是一个传统的异步回调 - 你需要遵循promise规范并返回一个新的承诺,用一个解析和拒绝处理程序包装它,如下所示:
return new Promise(function(resolve, reject) {
fs.writeFile("<filename.type>", data, '<file-encoding>', function(err) {
if (err) reject(err);
else resolve(data);
});
});
因此,在您的代码中,您可以在调用.then()
后立即使用它
.then(function(results) {
return new Promise(function(resolve, reject) {
fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
if (err) reject(err);
else resolve(data);
});
});
}).then(function(results) {
console.log("results here: " + results)
}).catch(function(err) {
console.log("error here: " + err);
});
说
const util = require('util')
const fs_writeFile = util.promisify(fs.writeFile)
https://nodejs.org/api/util.html#util_util_promisify_original
这比最高投票的答案更容易出错
最后,最新的node.js版本v10.3.0本身支持fs promise。
const fsPromises = require('fs').promises; // or require('fs/promises') in v10.0.0
fsPromises.writeFile(ASIN + '.json', JSON.stringify(results))
.then(() => {
console.log('JSON saved');
})
.catch(er => {
console.log(er);
});
您可以查看官方文档以获取更多详细信息。 https://nodejs.org/api/fs.html#fs_fs_promises_api
2017年9月更新:fs-promise
已被弃用,以支持fs-extra
。
我没有用它,但你可以看看fs-promise。它是一个节点模块:
代理所有异步fs方法,将它们公开为Promises / A +兼容的promise(when,Q等)。将所有同步方法传递为值。
const util = require('util')
const fs = require('fs');
const fs_writeFile = util.promisify(fs.writeFile)
fs_writeFile('message.txt', 'Hello Node.js')
.catch((error) => {
console.log(error)
});
为了易于使用异步转换所有回调承诺使用一些像“蓝鸟”的库。
.then(function(results) {
fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
if (err) {
console.log(err);
} else {
console.log("JSON saved");
return results;
}
})
}).catch(function(err) {
console.log(err);
});
尝试有希望的解决方案(蓝鸟)
var amazon = require('amazon-product-api');
var fs = require('fs');
var Promise = require('bluebird');
var client = amazon.createClient({
awsId: "XXX",
awsSecret: "XXX",
awsTag: "888"
});
var array = fs.readFileSync('./test.txt').toString().split('\n');
Promise.map(array, function (ASIN) {
client.itemLookup({
domain: 'webservices.amazon.de',
responseGroup: 'Large',
idType: 'ASIN',
itemId: ASIN
}).then(function(results) {
fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
if (err) {
console.log(err);
} else {
console.log("JSON saved");
return results;
}
})
}).catch(function(err) {
console.log(err);
});
});