早安,
我在使用NodeJs / Javascript时遇到困难。预期的行为是,console.log
使用以下库输出具有权限的“读取您的联系人”的Google Play商店中应用的名称:https://github.com/facundoolano/google-play-scraper/
但是,我的console.log
最后没有输出任何内容,似乎apps[i].appId
还是空的。这是我的代码:
gplay = require('google-play-scraper');
gplay.search({
term: "horoscope",
num: 40
}).then(function(apps) {
for (i = 1; i <= apps.length; i++) {
gplay.permissions({
appId: apps[i].appId,
short: true
}).then(function(perm) {
for (a = 1; a <= perm.length; a++) {
if (perm[a] == 'read your contacts') {
console.log(apps[i].appId)
}
}
}
)
}
}
);
答案 0 :(得分:1)
您不能将异步调用放在这样的for循环中。创建一个Promise数组,然后使用Promise.all等待对API的所有调用完成。
我已经根据您的代码示例创建了一个工作程序。我已将解释添加为嵌入式注释:
// use 'const' to define gplay because it doesn't get reassigned
const gplay = require('google-play-scraper');
gplay.search({
term: "horoscope",
num: 40
}).then(function(apps) {
// create an array to collect the calls to get permissions
// use 'const' to define it because it doesn't get reassigned
const getPermissions = [];
// arrays are zero based, start with 0, not with 1
// use 'let' to define 'i'
for (let i = 0; i < apps.length; i++) {
const appId = apps[i].appId;
// fill the array with Promises, i.e. call objects
// that get resolved with a result after a while
getPermissions.push(
gplay.permissions({
appId: appId,
short: true
}).then(function (perm) {
// we put our permissions in a result object
// along with the app ID
return {
appId: appId,
perm: perm
}
})
);
}
// Wait until all the promises are resolved after the
// Google Play API was called – we get an array of results
Promise.all(getPermissions).then(function(results) {
// iterate through the results array, get a result
// object for each iteration
for (let r = 0; r < results.length; r++) {
const result = results[r];
const appId = result.appId;
const perm = result.perm;
// arrays are zero based, start with 0, not with 1
// use 'let' to define 'a'
for (let a = 0; a < perm.length; a++) {
// always use "===", never use "=="!
if (perm[a] === 'read your contacts') {
console.log(appId)
}
}
}
})
});
请注意,这仍然是“入门代码”,这意味着可以使用Array.map,object destructuring,arrow functions等进行简化。我故意将其省略,因此更容易了解代码。
该代码的更高级版本:
const gplay = require('google-play-scraper');
gplay.search({
term: "horoscope",
num: 40
}).then(apps => {
const getPermissions = apps.map(app => {
const { appId } = app;
return gplay.permissions({
appId,
short: true
}).then(perm => ({
appId,
perm
}))
});
Promise.all(getPermissions).then(results =>
results.forEach(({ appId, perm }) =>
perm.forEach(p =>
p === 'read your contacts' && console.log(appId)
)
)
)
});