This question already has an answer here:
这个问题在这里已有答案:
- How do I return the response from an asynchronous call? 31 answers
如何从异步调用返回响应? 31个答案
Problem resolved on Asynchronously solution to check data from database kinds of loop clause
with this below code i can generate simple array as jsonArray into checkUserMobileNumberAsEwallet
function, but i can't pass it out of that to send inside client,
使用下面的代码,我可以生成简单的数组作为jsonArray到checkUserMobileNumberAsEwallet函数,但我无法将其传递出来发送到客户端内部,
with socket.emit('syncContacts', accountNumbers)
i get []
result on accountNumbers
, but into if (success) {
statement array successful created and pushed into accountNumbers
array
使用socket.emit('syncContacts',accountNumbers)我在accountNumbers上获得[]结果,但是if(成功){语句数组成功创建并推送到accountNumbers数组
socket.on('syncContacts', function (data) {
var accountNumbers = [];
for (var i = 0; i < data.length; i++) {
checkUserMobileNumberAsEwallet(data[i].mobileNumber, function (success) {
if (success) {
accountNumbers.push({ewalletNumber: this.mobileNumber});
console.log(accountNumbers);
}
}.bind({mobileNumber: data[i].mobileNumber}));
}
console.log(accountNumbers);
socket.emit('syncContacts', accountNumbers);
});
function checkUserMobileNumberAsEwallet(mobileNumber, callback) {
var mobileNumber = mobileNumber.substr(1, mobileNumber.length);
var query = "SELECT id FROM userEwallets WHERE ewalletNumber LIKE '%" + mobileNumber + "'";
connection.query(query, function (err, results) {
if (err) return callback(false);
if (results.length === 0)
return callback(false);
else {
return callback(true);
}
});
}
Updated after post comments:
socket.on('syncContacts', function (data) {
//console.log(accountNumbers);
//socket.emit('syncContacts', accountNumbers);
async.parallel(
[
function (callback) {
var accountNumbers = [];
for (var i = 0; i < data.length; i++) {
checkUserMobileNumberAsEwallet(data[i].mobileNumber, function (success) {
if (success) {
accountNumbers.push({ewalletNumber: this.mobileNumber});
console.log(accountNumbers);
}
}.bind({mobileNumber: data[i].mobileNumber}));
}
callback(success, accountNumbers);
}
],
function (success, results) {
console.log("results " + results.toString());
socket.emit('syncContacts', results);
});
});
function checkUserMobileNumberAsEwallet(mobileNumber, callback) {
var mobileNumber = mobileNumber.substr(1, mobileNumber.length);
var query = "SELECT id FROM userEwallets WHERE ewalletNumber LIKE '%" + mobileNumber + "'";
connection.query(query, function (err, results) {
if (err) return callback(false);
if (results.length === 0)
return callback(false);
else {
return callback(true);
}
});
}
2 个解决方案
#1
0
Based on our code, it seems like checkUserMobileNumberAsEwallet
is an asynchronous event, which accepts a function callback. That would mean that the for-loop would execute, which would queue up executions to checkUserMobileNumberAsEwallet
. Immediately after the for-loop executes, console.log would correctly output the empty array accountNumbers
and emit the event through the socket. Then the callback functions to each checkUserMobileNumberAsEwallet
execution would begin to execute, and log the accountNumbers
array which now has data.
根据我们的代码,checkUserMobileNumberAsEwallet似乎是一个异步事件,它接受一个函数回调。这意味着for循环将执行,这会将执行排队到checkUserMobileNumberAsEwallet。在for循环执行之后,console.log会立即正确输出空数组accountNumbers并通过套接字发出事件。然后每个checkUserMobileNumberAsEwallet执行的回调函数将开始执行,并记录现在有数据的accountNumbers数组。
This can be solved in a few ways, but likely the easiest and most readable would be to create Promises, and act on the Promises when they resolve. Personally I like the 'when' promise library, but many libraries could help to solve this problem. https://github.com/cujojs/when/blob/master/docs/api.md#whensettle
这可以通过几种方式解决,但最简单和最易读的可能是创建Promise,并在解决时对Promise采取行动。就个人而言,我喜欢“何时”的承诺库,但许多图书馆可以帮助解决这个问题。 https://github.com/cujojs/when/blob/master/docs/api.md#whensettle
#2
0
The problem is that you have no control over when the code inside the callback executes, and it ends up executing after you've already called socket.emit
.
问题是你无法控制回调中的代码何时执行,并且在你已经调用了socket.emit之后它最终会执行。
You can either a) use an async aggregator to call a callback for each successful mobile number and then, when all of those have finished, call the socket.emit call OR b) do something like what I did below. Alter your checkUserMobileNumberAsEwallet function to accept and verify an array of mobile numbers, and pass the successful numbers to your callback function
您可以a)使用异步聚合器为每个成功的移动号码调用回调,然后,当所有这些都完成后,调用socket.emit调用或b)执行类似我在下面所做的操作。更改checkUserMobileNumberAsEwallet函数以接受并验证一组移动号码,并将成功的号码传递给您的回调函数
Try the following:
请尝试以下方法:
socket.on('syncContacts', function (data) {
var accountNumbers = [];
var mobileNumbers = [];
for (var i = 0; i < data.length; i++) {
mobileNumbers.push(data[i].mobileNumber);
}
checkUserMobileNumberAsEwallet(mobileNumbers, function (successfulNumbers) {
if (successfulNumbers.length > 0) {
for (var i = 0; i < successfulNumbers.length; i++) {
accountNumbers.push({ewalletNumber: successfulNumbers[i]});
}
socket.emit('syncContacts', accountNumbers);
}
}.bind({mobileNumbers: mobileNumbers}));
});
#1
0
Based on our code, it seems like checkUserMobileNumberAsEwallet
is an asynchronous event, which accepts a function callback. That would mean that the for-loop would execute, which would queue up executions to checkUserMobileNumberAsEwallet
. Immediately after the for-loop executes, console.log would correctly output the empty array accountNumbers
and emit the event through the socket. Then the callback functions to each checkUserMobileNumberAsEwallet
execution would begin to execute, and log the accountNumbers
array which now has data.
根据我们的代码,checkUserMobileNumberAsEwallet似乎是一个异步事件,它接受一个函数回调。这意味着for循环将执行,这会将执行排队到checkUserMobileNumberAsEwallet。在for循环执行之后,console.log会立即正确输出空数组accountNumbers并通过套接字发出事件。然后每个checkUserMobileNumberAsEwallet执行的回调函数将开始执行,并记录现在有数据的accountNumbers数组。
This can be solved in a few ways, but likely the easiest and most readable would be to create Promises, and act on the Promises when they resolve. Personally I like the 'when' promise library, but many libraries could help to solve this problem. https://github.com/cujojs/when/blob/master/docs/api.md#whensettle
这可以通过几种方式解决,但最简单和最易读的可能是创建Promise,并在解决时对Promise采取行动。就个人而言,我喜欢“何时”的承诺库,但许多图书馆可以帮助解决这个问题。 https://github.com/cujojs/when/blob/master/docs/api.md#whensettle
#2
0
The problem is that you have no control over when the code inside the callback executes, and it ends up executing after you've already called socket.emit
.
问题是你无法控制回调中的代码何时执行,并且在你已经调用了socket.emit之后它最终会执行。
You can either a) use an async aggregator to call a callback for each successful mobile number and then, when all of those have finished, call the socket.emit call OR b) do something like what I did below. Alter your checkUserMobileNumberAsEwallet function to accept and verify an array of mobile numbers, and pass the successful numbers to your callback function
您可以a)使用异步聚合器为每个成功的移动号码调用回调,然后,当所有这些都完成后,调用socket.emit调用或b)执行类似我在下面所做的操作。更改checkUserMobileNumberAsEwallet函数以接受并验证一组移动号码,并将成功的号码传递给您的回调函数
Try the following:
请尝试以下方法:
socket.on('syncContacts', function (data) {
var accountNumbers = [];
var mobileNumbers = [];
for (var i = 0; i < data.length; i++) {
mobileNumbers.push(data[i].mobileNumber);
}
checkUserMobileNumberAsEwallet(mobileNumbers, function (successfulNumbers) {
if (successfulNumbers.length > 0) {
for (var i = 0; i < successfulNumbers.length; i++) {
accountNumbers.push({ewalletNumber: successfulNumbers[i]});
}
socket.emit('syncContacts', accountNumbers);
}
}.bind({mobileNumbers: mobileNumbers}));
});