我有一些我无法理解的代码,我试图使用回调返回对象数组,我有一个函数返回值,然后将其压入数组,但是我无法在函数外部访问它,我在这里做一些愚蠢的事情,但无法分辨(我对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中使用哪些工具来去做。
您的核心问题是时间问题。该createOrUpdateMarket()
功能可能是异步的。这意味着它在调用该函数时开始其操作,然后在将来的某个时间调用其回调。同时,其余代码将继续运行。因此,您试图在调用回调之前访问数组。
因为您无法确切知道何时会调用该回调,所以唯一可以可靠使用回调数据的位置是在回调内部或在回调内部被调用的位置。
要知道createOrUpdateMarket()
所有这些操作何时全部完成,您将必须编写代码,尤其是要知道所有这些操作何时完成,并且您不能依赖简单的for
循环。现代的方法是使用promise,promise提供工具来帮助您管理一个或多个异步操作的时序。
此外,如果您想累积for
in中的循环结果marketArray
,则必须在for
循环之前而不是for
循环内部声明并初始化它。以下是几种解决方案:
手动编码解决方案
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库增强了承诺
蓝鸟的Promise库提供Promise.map()
了将迭代您的数据数组并生成一系列异步获取的结果的功能。
// 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()
which将创建结果数组。
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
}
});
问题内容: 我有一个从或指令属性或任何其他属性中获得的字符串,我想基于此在作用域上创建一个变量。所以: 但是,如果字符串包含一个或多个点,我想将其拆分并实际上“向下钻取”到作用域中。所以应该成为。这意味着简单版本不起作用! 在读取基于字符串的变量时,您可以通过做来获得这种行为,但是在分配值时如何实现呢? 问题答案: 我发现的解决方案是使用$ parse。 “将Angular表达式转换为函数。” 如
我正在尝试从我的node.js应用程序中设置一个全局环境变量。 目标是: 重启APP时,仍应设置环境变量 打开新外壳时,它应该可用 如果可能:重新启动时,与 1 相同。 它应该适用于 Linux、Mac OS X(并且需要一个备用的 SET 命令来访问窗口) 以下是我所做的: 但这导致了 我没有在Windows上测试这个,但在Mac OS X(和Linux)上,bash上正确的命令是。对于Wind
我有一个考试示例,它询问我是否可以访问包含值1的x变量?解决方案是我可以,但我感兴趣的是具体怎么做?
我目前正在用下面的代码从Google表单中获取所有值,但是在从那里获取所有值之后,现在如何在另一个表单中设置它们呢? var ss=电子表格应用程序。openById(ID); var值=ss。getDataRange()。getValues(); var ss1=电子表格应用程序。openById(ID1); 我没能做到,有没有办法用for循环做到?
问题内容: 经过数小时令人沮丧的搜索,我觉得我需要在这里提交我的问题。如果此问题以前得到过解答,我事先表示歉意,但是到目前为止,我的搜索都没有帮助。所以这是我的问题: 我的JavaScript代码正在创建一个对象,该对象由AngularJS修改和监视。对于某些事件(例如加载对象的先前设置),我希望从范围之外更改该对象的属性。问题是输入不会改变… 这是我希望如何执行这些更改的示例: HTML代码:
问题内容: 一个简单的问题:如何在html中设置作用域值,以供控制器读取? JSFiddle:http : //jsfiddle.net/ncapito/YdQcX/ 问题答案: 在循环内分配变量时不起作用。用 尾随会停止对任何文本求值的Angular表达式。 然后,您只需调用即可输出变量值。 我发现在迭代多个嵌套数组时这非常有用,我想将当前的迭代信息保留在一个变量中,而不是多次查询。