在函数上异步生成生成的数组并将其从框中传递出来[重复]

时间:2022-10-16 21:25:40

This question already has an answer here:

这个问题在这里已有答案:

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}));
});