Node.JS如何在当前范围之外设置变量 [英] Node.JS How to set a variable outside the current scope

查看:102
本文介绍了Node.JS如何在当前范围之外设置变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码,我无法理解,我试图使用回调返回一个对象数组,我有一个函数,返回值,然后将它们推入一个数组,但我无法访问此外函数,我在这里做了一些蠢事,但不知道是什么(我对Node.JS很新)

I have some code that I cant get my head around, I am trying to return an array of object using a callback, I have a function that is returning the values and then pushing them into an array but I cant access this outside of the function, I am doing something stupid here but can't tell what ( I am very new to Node.JS )

                    for (var index in res.response.result) {
                    var marketArray = [];
                    (function () {
                        var market = res.response.result[index];
                        createOrUpdateMarket(market, eventObj , function (err, marketObj) {
                            marketArray.push(marketObj)
                            console.log('The Array is %s',marketArray.length) //Returns The Array is 1.2.3..etc
                        });
                        console.log('The Array is %s',marketArray.length) // Returns The Array is 0

                    })();

                }


推荐答案

你有这里有多个问题。核心问题是了解异步响应如何工作以及何时执行代码。但是,除此之外,您还必须学习如何在循环中管理多个异步响应,以及如何知道所有响应何时完成以及如何按顺序获取结果以及哪些工具最好在node.js中使用那样做。

You have multiple issues going on here. A core issue is to gain an understanding of how asynchronous responses work and which code executes when. But, in addition to that you also have to learn how to manage multiple async responses in a loop and how to know when all the responses are done and how to get the results in order and what tools can best be used in node.js to do that.

你的核心问题是时间问题。 createOrUpdateMarket()函数可能是异步的。这意味着它在调用函数时启动它的操作,然后在将来的某个时候调用它的回调。与此同时,其余代码继续运行。因此,您正在尝试在调用回调之前访问数组。

Your core issue is a matter of timing. The createOrUpdateMarket() function is probably asynchronous. That means that it starts its operation when the function is called, then calls its callback sometime in the future. Meanwhile the rest of your code continues to run. Thus, you are trying to access the array BEFORE the callback has been called.

因为您无法准确知道何时将调用该回调,所以您可以可靠地使用该唯一的地方回调数据在回调内或从回调中调用的内容。

Because you cannot know exactly when that callback will be called, the only place you can reliably use the callback data is inside the callback or in something that is called from within the callback.

您可以在此处阅读有关异步/回调问题详细信息的更多信息:为什么我的变量在未改变之后我在函数内修改它? - 异步代码参考

You can read more about the details of the async/callback issue here: Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

要知道这些 createOrUpdateMarket()操作的全部系列都是全部完成后,您将不得不编写代码以了解所有这些内容何时完成,并且您不能依赖简单的进行循环。现代的方法是使用promises,它提供工具来帮助你管理一个或多个异步操作的时间。

To know when a whole series of these createOrUpdateMarket() operations are all done, you will have to code especially to know when all of them are done and you cannot rely on a simple for loop. The modern way to do that is to use promises which offer tools for helping you manage the timing of one or more asynchronous operations.

此外,如果你想积累结果从 for 循环 marketArray ,您必须在之前声明并初始化循环,而不是中的循环。以下是几种解决方案:

In addition, if you want to accumulate results from your for loop in marketArray, you have to declare and initialize that before your for loop, not inside your for loop. Here are several solutions:

手动编码解决方案

var len = res.response.result.length;
var marketArray = new Array(len), cntr = 0;
for (var index = 0, index < len; index++) {
    (function(i) {
        createOrUpdateMarket(res.response.result[i], eventObj , function (err, marketObj) {
            ++cntr;
            if (err) {
                // need error handling here
            }
            marketArray[i] = marketObj;
            // if last response has just finished
            if (cntr === len) {
                // here the marketArray is fully populated and all responses are done
                // put your code to process the marketArray here
            }
        });
    })(index);
}

内置于Node.js的标准承诺

// make a version of createOrUpdateMarket that returns a promise
function createOrUpdateMarketAsync(a, b) {
    return new Promise(function(resolve, reject) {
        createOrUpdateMarket(a, b, function(err, marketObj) {
            if (err) {
                reject(err);
                return;
            }
            resolve(marketObj);
        });
    });
}

var promises = [];
for (var i = 0; i < res.response.result.length; i++) {
    promises.push(createorUpdateMarketAsync(res.response.result[i], eventObj));
}
Promise.all(promises).then(function(marketArray) {
    // all results done here, results in marketArray
}, function(err) {
    // an error occurred
});

使用Bluebird Promise库增强承诺

bluebird promise库提供 Promise.map(),它将迭代你的数据数组并产生一组异步获得的结果。

The bluebird promise library offers Promise.map() which will iterate over your array of data and produce an array of asynchronously obtained results.

// make a version of createOrUpdateMarket that returns a promise
var Promise = require('bluebird');
var createOrUpdateMarketAsync = Promise.promisify(createOrUpdateMarket);

// iterate the res.response.result array and run an operation on each item
Promise.map(res.response.result, function(item) {
    return createOrUpdateMarketAsync(item, eventObj);
}).then(function(marketArray) {
    // all results done here, results in marketArray
}, function(err) {
    // an error occurred
});

异步库

您还可以使用异步库来帮助管理多个异步操作。在这种情况下,您可以使用 async.map()这将创建一个结果数组。

You can also use the async library to help manage multiple async operations. In this case, you can use async.map() which will create an array of results.

var async = require('async');
async.map(res.response.result, function(item, done) {
    createOrUpdateMarker(item, eventObj, function(err, marketObj) {
        if (err) {
            done(err);
        } else {
            done(marketObj);
        }
    });
}, function(err, results) {
    if (err) {
        // an error occurred
    } else {
        // results array contains all the async results
    }
});

这篇关于Node.JS如何在当前范围之外设置变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆