【问题标题】:Returning array after being filled in async function - Node.js填写异步函数后返回数组 - Node.js
【发布时间】:2018-11-29 13:38:03
【问题描述】:

我想从 API 访问一些数据,但遇到了问题。我的代码正在从 API 中获取一些数据,并将其与 API 的本地副本进行比较。如果本地副本与从 API 获取的副本不匹配,我希望它在数组中存储一些数据。获取和比较工作正常。当我尝试填充数组并想将其归还时,问题就出现了。 request 函数是异步的,所以我最后的返回值将是未定义的。我的函数checkForDiff 应该在 for 循环完成后返回这个数组,因为在 for 循环之后数组应该填充我需要的信息。我是 Nodejs 的新手,所以我真的不知道如何解决它。我需要在返回之前填充数组,但是异步 request 调用给我带来了问题。我怎样才能实现这种行为? 提前感谢您的帮助

function checkForDiff(){
 let outdatedLanguages = [];

 var options = {
   url: 'https://xxxxxxxxxxxxxxxxxxxxxxxxx',
   headers: {'Key': 'xxxxxxxxxxxxxxxxxxxxxx'}
 };
 for(let index = 0; index < locales.length; index++){
    //Change url for new https request
    options.url = `https://xxxxxxx?locale=${locales[index].symbol}`
    //Send new https request to API
    request(options, (error, response, body)=>{
       var localState = hash(JSON.parse(filesystem.readFileSync(`./cards/cards-${locales[index].symbol}.json`)));
       var recentState = hash(JSON.parse(body));
       /If the local card base is not up to date, add locale to array
       if(localState !== recentState){
        outdatedLanguages.push(locales[index].symbol);
       }
    );
  }
 //Return outdatedLanguages array
 return outdatedLanguages;
}

【问题讨论】:

标签: javascript node.js asynchronous


【解决方案1】:

要获得正确的数据,您需要使用 Promise。使用 Promise 代替请求回调。

因为checkForDiff() 是一个异步函数,您应该从该函数返回一个promise,而不是尝试返回outdatedLanguages。对于您的情况,您需要使用 Promise.all() 函数,因为您有多个异步函数。从某种意义上说,Promise.all() 等待所有任务完成。在您使用该函数的代码的另一部分中,您应该知道该函数是一个承诺,因此您应该相应地使用它。基本上,你可以这样做。

function checkForDiff() {

    let outdatedLanguages = [];
    let promises = [];

    var options = {
        url: 'https://xxxxxxxxxxxxxxxxxxxxxxxxx',
        headers: { 'Key': 'xxxxxxxxxxxxxxxxxxxxxx' }
    };
    for (let index = 0; index < locales.length; index++) {
        //Change url for new https request
        options.url = `https://xxxxxxx?locale=${locales[index].symbol}`

        promises.push(/* request as promise */);
    }

    return Promise.all(promises).then(() => outdatedLanguages);

}

你这样调用函数。

checkForDiff().then((outdatedLanguages) => {
    // outdatedLanguages is the array you want
})

对于请求承诺,您可以使用request-promise 包。使用命令npm install --save request-promise。然后包含包var rp = require('request-promise');。示例请求如下:

var options = {
    uri: 'https://api.github.com/user/repos',
    qs: {
        access_token: 'xxxxx xxxxx' // -> uri + '?access_token=xxxxx%20xxxxx'
    },
    headers: {
        'User-Agent': 'Request-Promise'
    },
    json: true // Automatically parses the JSON string in the response
};

rp(options)
    .then(function (repos) {
        console.log('User has %d repos', repos.length);
    })
    .catch(function (err) {
        // API call failed...
    });

【讨论】:

  • 感谢您的回答。这对我帮助很大。
猜你喜欢
  • 2020-09-12
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 2021-05-17
相关资源
最近更新 更多