以下代码应该将一个字符串作为输入(此处为 inMessage)并拆分其中的单词。然后它在 firebase 实时数据库中查询关联的键、值,并用检索到的值替换该词。这个修改后的字符串必须作为输出发回。
现在,我似乎找不到使 'msg' 成为正确字符串的方法。如果我对字符串而不是 msg 进行硬编码,则会正确呈现输出。那么如何让 msg 成为一个合适的字符串呢?(我试过用 ""、toString()、String() 和 JSON.stringify() 将它括起来 - 这里一定有我遗漏的东西)
function queryDB(senderID, inMessage){
var arr=inMessage.split(" ");
console.log(arr);
var i;
console.log('inside queryDB');
var msg="";
for(i=0;i<arr.length;i++){
var x = 'https://oreo-fd681.firebaseio.com/'+arr[i]+'.json';
request({
url: x,
method: 'GET'
}, function(error, response, body) {
console.log(response.body);
if (error) {
console.log('Error making api call ' + error);
} else if (response.body.error){
console.log('Error making api call' + response.body.error);
}
else if(response==null) {
//if not found in DB concatenate whatever arr[i] holds
callback1();
}
else {
//else concatenate the found key
var n=JSON.parse(response.body);
//remove the quotes associated with key value
callback2(JSON.stringify(n.key).replace(/['"]+/g, ''));
}
});
function callback1(){
msg+=(arr[i]);
msg+=" ";
console.log(msg);
}
function callback2(add){
msg+=(add);
msg+=" ";
console.log(msg);
}
}
//add quotes back - not sure of this
sendMessageToUser(senderID, ("\""+msg+"\""));
}
您的问题与request
回调的异步性质有关:
sendMessageToUser
在任何请求返回结果之前执行。i
是 with 声明的var
,for 的值i
将arr.length
在任何请求返回结果之前到达,因此callback1
该值将无用——它将始终引用arr[arr.length]
,这是未定义的msg +=
可能会构建一个键顺序错误的字符串。callback1
和callback2
喜欢那个。下面是一种方法,它坚持简单的旧回调模式。它有这些变化:
sendMessageToUser
i
是let
在for
构造中声明的,因此它具有块作用域,即您为循环的每次迭代获得一个单独的变量。这样,当您在回调中引用它时,它将恰好是该版本的变量。callback1
和callback2
功能被替换为代码,可以处理两种变化(当response === null
与否)。这是代码:
function queryDB(senderID, inMessage){
var arr = inMessage.split(" ");
console.log(arr);
console.log('inside queryDB');
// At first, use an array, so you can put back the asynchronous results in the correct order
var msgArray = [];
// Keep track of the number of asynchronous results you are still waiting for
var leftOver = arr.length;
// Use LET to make loop variable block scoped: that way you'll have the same value for
// it when the asynchronous callback is called
for(let i=0; i < arr.length; i++) {
var x = 'https://oreo-fd681.firebaseio.com/'+arr[i]+'.json';
request({
url: x,
method: 'GET'
}, function(error, response, body) {
console.log(response.body);
if (error) {
console.log('Error making api call ' + error);
} else if (response.body.error){
console.log('Error making api call' + response.body.error);
}
else {
// Treat the two cases with the ternary operator
// and put the result at the correct index
msgArray[i] = response === null ? arr[i] : JSON.parse(response.body).key;
console.log(msgArray);
// Detect when you have collected all results
leftOver--;
if (!leftOver) {
// Join all the words together into one string and send it
sendMessageToUser(senderID, msgArray.join(' '));
}
}
});
}
}
就像我说的,我坚持使用回调模式,但是当你使用 Promise 和Promise.all
方法时,事情会变得更好。你应该调查一下。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句