首页 > 解决方案 > NodeJs Console.log 不输出结果

问题描述

再会,

我在使用 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)

                        }


                    }


                }


            )
        }

    }
);

标签: javascriptnode.jsgoogle-api

解决方案


您不能在这样的 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对象解构箭头函数等对其进行简化。我故意将其省略,以便更容易理解代码。

更高级的代码版本:

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

推荐阅读