我的主要功能如下:
function main(body) {
var deferred = Q.defer();
// Make an API request
console.log("body :"+ body);
var jsonbody = JSON.parse(body);
partialSequence = jsonbody['partialSequence'];
uniqID = jsonbody['uniq'];
resultLength = jsonbody['resultLength'];
console.log("resultLength :"+ resultLength);
if (partialSequence.indexOf("G") > -1) ns.push("G");
if (partialSequence.indexOf("A") > -1) ns.push("A");
if (partialSequence.indexOf("C") > -1) ns.push("C");
if (partialSequence.indexOf("T") > -1) ns.push("T");
uniq = uniqID;
var sequence = Promise.resolve();
for (var i = 0; i < resultLength; i++) {
location = i;
for (var j = 0; j < nuclides.length; j++) {
n = nuclides[j]
var promise = getLocation(n, location, uniq);
promise.then(function(values) {
console.log("location :"+values[0] + " "+ values[1]);
if (expressed) {
isExpressed = true;
if(route > 0) {
for (var key in resultSeq) {
if (resultSeq.hasOwnProperty(key)) {
var temp = resultSeq[key]
delete resultSeq[key];
temp = temp.concat(n);
resultSeq[temp] = temp;
}
}
} else {
resultSeq[n] = n;
}
}
});
}
if (isExpressed) route++; //used to check if we append to existing sequences.
}
deferred.resolve();
return deferred.promise
}
function getLocation(n, location, uniq) {
var expressed
var deferred = Q.defer();
Q.ninvoke(request, 'get', {
url: "https://myapi.com/location?"+"location="+location+"&"+"nucleotide="+n+"&"+"uniq= "+uniq
}).spread(function(response, body) {
expressed=1;
var jsonbody = JSON.parse(body);
return [jsonbody["expressed"], location];
});
return deferred.promise
}
当我在console.log中时,位置values[0]
出现故障时应该是0,1,2 ....... n。我怎样才能做到这一点?非常感谢!
答案 0 :(得分:0)
首先,让我们通过将代码放入一个传递位置索引的函数来简化内部for
循环,然后在代码完成时返回一个新的promise。由于您只是处理数组的内容,因此可以使用.reduce()
设计模式为每个数组元素链接一个promise。这将连续执行所有这些:
function innerWork(locationIndex) {
// process the nuclides array for a given locationIndex
return nuclides.reduce(function (p, n) {
return p.then(function () {
// now process a single locationIndex
return getLocation(n, locationIndex, uniq).then(function (values) {
console.log("location :" + values[0] + " " + values[1]);
if (expressed) {
isExpressed = true;
if (route > 0) {
for (var key in resultSeq) {
if (resultSeq.hasOwnProperty(key)) {
var temp = resultSeq[key]
delete resultSeq[key];
temp = temp.concat(n);
resultSeq[temp] = temp;
}
}
} else {
resultSeq[n] = n;
}
}
});
});
}, Promise.resolve());
}
然后,可以通过手动链接到单个promise来完成外部循环:
var sequence = Promise.resolve();
for (var i = 0; i < resultLength; i++) {
(function(index) {
sequence = sequence.then(function() {
return innerWork(index);
});
})(i);
}
这使用内部IIFE来捕获闭包中的循环索引,因此当innerWork(index)
函数调用稍后作为promises链并及时执行时,我们有正确的值。
这样做是建立一系列承诺,这些承诺全部链接在一起然后从前面开始并一个接一个地执行。
总而言之,你最终得到了这个:
function main(body) {
// Make an API request
console.log("body :" + body);
var jsonbody = JSON.parse(body);
partialSequence = jsonbody['partialSequence'];
uniqID = jsonbody['uniq'];
resultLength = jsonbody['resultLength'];
console.log("resultLength :" + resultLength);
if (partialSequence.indexOf("G") > -1) ns.push("G");
if (partialSequence.indexOf("A") > -1) ns.push("A");
if (partialSequence.indexOf("C") > -1) ns.push("C");
if (partialSequence.indexOf("T") > -1) ns.push("T");
uniq = uniqID;
function innerWork(locationIndex) {
// process the nuclides array for a given locationIndex
return nuclides.reduce(function (p, n) {
return p.then(function () {
// now process a single locationIndex
return getLocation(n, locationIndex, uniq).then(function (values) {
console.log("location :" + values[0] + " " + values[1]);
if (expressed) {
isExpressed = true;
if (route > 0) {
for (var key in resultSeq) {
if (resultSeq.hasOwnProperty(key)) {
var temp = resultSeq[key]
delete resultSeq[key];
temp = temp.concat(n);
resultSeq[temp] = temp;
}
}
} else {
resultSeq[n] = n;
}
}
});
});
}, Promise.resolve());
}
var sequence = Promise.resolve();
for (var i = 0; i < resultLength; i++) {
(function (index) {
sequence = sequence.then(function () {
return innerWork(index);
});
})();
}
if (isExpressed) route++; //used to check if we append to existing sequences.
return sequence;
}
此外,请记住您的其他问题/答案中改进的getLocation()
功能:
function getLocation(n, location, uniq) {
var expressed
return Q.ninvoke(request, 'get', {
url: "https://myapi.com/location?"+"location="+location+"&"+"nucleotide="+n+"&"+"uniq= "+uniq
}).spread(function(response, body) {
expressed = 1;
var jsonbody = JSON.parse(body);
return [jsonbody["expressed"], location];
});
}
P.S。,您的原始代码有几个您引用的未声明变量。请确保在适当的范围内声明所有变量。例如,我不知道expressed
函数中的main()
变量在哪里被声明,并且有很多变量我没有看到本地声明您引用的main()
中的内容。这通常是一种不好的做法。