我正在尝试实现一个遍历列表的for循环,然后只有在找到第一个函数结果时调用两个函数。
问题是第二个函数(search.similar)可能需要更长时间才能获取结果。
使用下面的代码,当我运行时,(search.locate)的所有适当输出都是正确的,但只有myList的最后一个元素的结果存储在(search.similar)函数中。
即。 all_results = [[cat_res1,mouse_res2],[dog_res1,mouse_res2],[mouse_res1,mouse_res2]]
如何解决此问题,以正确的顺序附加正确的结果?
即。 all_results = [[cat_res1,cat_res2],[dog_res1,dog_res2],[mouse_res1,mouse_res2]]
var search = require('./search');
var myList = ['cat','dog','mouse'];
var all_results = [];
for (i=0; i<myList.length; i++){
/* locate function*/
search.locate(myList[i], function (err, searchResult){
if (err){
console.log("Error");
return;
}
if (!searchResult){
console.log("Cannot find it");
return;
}
/*similarity function*/
/* seems to take longer*/
search.similar(myList[i], function (err, similarResult){
if (err){
return;
}
if (!similarResult){
return;
}
var res1 = searchResult.data;
var res2 = similarResult.data;
/* append results to array*/
all_results.push([res1,res2]);
}
});
}
答案 0 :(得分:0)
Javascript可以被认为是异步的,因为特定函数的执行不一定同步发生,然而将JavaScript描述为异步可能会产生误导。更准确地说,JavaScript是同步的,并且具有各种回调机制的单线程&#34;
为了实现您的目标,尽管您可能仍然会遇到顶部数组的一些排序问题,但您需要将.similar()
调用包装在另一个带有两个参数的函数中。您对&#34;项目&#34;的引用在顶部搜索正在改变:
function searchNestedSimilar(item, topRes) {
search.similar(item, function (err, similarResult) {
if (err){
return;
}
if (!topRes){
return;
}
var res1 = topRes.data
var res2 = similarResult.data
// append results to array
all_results.push([res1,res2])
}
}
function searchLocate(item) {
search.locate(item, function (err, searchResult) {
if (err){
console.log("Error");
return;
}
if (!searchResult){
console.log("Cannot find it");
return;
}
searchNestedSimilar(item, searchResults);
}
我封装了两个调用以保持模块化,但是因为&#34; item&#34;在闭包中,你真的只需要searchLocate()
函数来包装你在迭代过程中捕获你的项目引用。
答案 1 :(得分:0)
这是Promises的一个很好的例子(参见Bluebird JS,例如http://bluebirdjs.com/docs/getting-started.html)或者你可以用 async.map()。
这个页面也很好地讨论了它。 http://promise-nuggets.github.io/articles/14-map-in-parallel.html
还有很多Stack Overflow讨论Promise。例如Understanding JS Promises。
如何使用Promise编写此代码的粗略示例:
var search = require('./search');
var myList = ['cat','dog','mouse']
var all_results = []
var Promise = require('bluebird');
var locate = Promise.promisify(search.locate);
var similar = Promise.promisify(search.similar);
for (i = 0; i < myList.length; i++){
// locate function
locate(myList[i], function (err, searchResult) {
if (err) {
console.log("Error");
return;
}
if (!searchResult){
console.log("Cannot find it");
return;
}
}).then(function(result) {
//similarity function
similar(myList[i], function (err, similarResult) {
if (err){
return;
}
if (!similarResult){
return;
}
var res1 = searchResult.data
var res2 = similarResult.data
// append results to array
all_results.push([res1,res2])
}).finally(function() {
// NOP
});
});
}