setTimeout只在循环中运行一次

My goal is to perform the javascript function every X amount of seconds. I've read that setInterval should be used but I don't believe so in my case. I also don't want the variables to have to be resent just incase the user decides to change things before everything was officially sent

For example, I put 60 in time and 5 in amount but it waited 60 seconds and then just sent 5 instead, 1 text every 60 seconds until it had sent 5 texts

my javascript

    $('input[name="sendtxt"]').click(function(e) {
        sendText(e);
    });

function sendText(e) {
    e.preventDefault();
    var phonenum = $('input[name="phonenum"]').val();
    var provider = $('select[name="provider"]').val();
    var message = $('textarea[name="message"]').val();
    var otherprov = $('input[name="otherprov"]').val();
    var amount = $('input[name="amount"]').val();
    var time = $('input[name="time"]').val() * 1000;
    var sendmsg;
    for (sendmsg = 1; sendmsg <= amount; sendmsg++) {
        setTimeout(function() {
            $.ajax({
                type: 'POST',
                data: {
                    provider: provider,
                    message: message,
                    phonenum: phonenum,
                    amount: amount,
                    otherprov: otherprov,
                    time: time
                },
                url: 'send.php',
                success: function(data) {
                    console.log('Success. Sent ' + sendmsg + " texts.");
                },
                error: function(xhr, err) {
                    console.log("readyState: " + xhr.readyState + "
status: " + xhr.status);
                    console.log("responseText: " + xhr.responseText);
                }
            });
        }, time);
    }

and my PHP

<?php


$to = $_POST["phonenum"];
$provider = $_POST["provider"];

$otherprov = $_POST["otherprov"];
$fixedotherprov = str_replace("otherprovider", "", $otherprov);


$completenum = $to . $provider . $fixedotherprov;
$completenum = str_replace('otherprovider', '', $completenum);
$subject = 'Hello';
$message = $_POST["message"];
$headers = 'From: Daniel';
$amount = $_POST["amount"];

//for ($x = 0; $x < $amount; $x++) {
    mail($completenum, $subject, $message, $headers);
//}

?>
dpjjr42626
dpjjr42626 注意:setTimeout将在单线程中运行
5 年多之前 回复

2个回答

setTimeoutis an asynchronous function. The timeout events are defined in your loop from sendmsg = 1 to sendmsg <= amount. After executing the for loop, rest of the code below the for loop is being executed until the timeout event fires. When the timeout events are fired, the value of sendmsg is equal to amount+1 as the loop is already finished execution. Therefore all the timeout events gets value of sendmsgas amout+1 leading the unexpected behaviour..

In the code below, a temporary scope is defined at each iteration which gives different sendmsg value to each timeout event.

You also have to schedule different times as the timeout time value in each iteration in order to execute them in different timeouts.

Modify your code like this..

function sendText(e) {
    e.preventDefault();
    var phonenum = $('input[name="phonenum"]').val();
    var provider = $('select[name="provider"]').val();
    var message = $('textarea[name="message"]').val();
    var otherprov = $('input[name="otherprov"]').val();
    var amount = $('input[name="amount"]').val();
    var time = $('input[name="time"]').val();
    var sendmsg;
    for (sendmsg = 1; sendmsg <= amount; sendmsg++) {
            (function(sendmsg){
               setTimeout(function() {
                $.ajax({
                    type: 'POST',
                    data: {
                        provider: provider,
                        message: message,
                        phonenum: phonenum,
                        amount: amount,
                        otherprov: otherprov,
                        time: time * 1000 * sendmsg
                    },
                    url: 'send.php',
                    success: function(data) {
                        console.log('Success. Sent ' + sendmsg + " texts.");
                    },
                    error: function(xhr, err) {
                        console.log("readyState: " + xhr.readyState + "
status: " + xhr.status);
                        console.log("responseText: " + xhr.responseText);
                    }
                });
            }, time * 1000 * sendmsg);
           })(sendmsg);
        }
}
doutang8098
doutang8098 然后,您必须在每次迭代时更改超时函数中使用的时间值。 我改变了代码。 检查它现在是否有效..
5 年多之前 回复
duanfei8399
duanfei8399 我把你的代码放进去了,我相信它现在等到时间,然后在那之后它会立即发送数量。 我不确定我是否清楚,但目标是它每次发送一定数量的文本,每次1个文本
5 年多之前 回复

this is a matter of scope.

read more about Javascript closure (scoped) functions: http://brackets.clementng.me/post/24150213014/example-of-a-javascript-closure-settimeout-inside

change your code to:

for (sendmsg = 1; sendmsg <= amount; sendmsg++) {
    (function(){
        setTimeout(function(_provider, _message, _phonenum, _amount, _otherprov, _time, _sendmsg) {
            $.ajax({
                type: 'POST',
                data: {
                    provider: _provider,
                    message: _message,
                    phonenum: _phonenum,
                    amount: _amount,
                    otherprov: _otherprov,
                    time: _time
                },
                url: 'send.php',
                success: function(data) {
                    console.log('Success. Sent ' + _sendmsg + " texts.");
                },
                error: function(xhr, err) {
                    console.log("readyState: " + xhr.readyState + "
status: " + xhr.status);
                    console.log("responseText: " + xhr.responseText);
                }
            });
        }, time);
    })(provider, message, phonenum, amount, otherprov, time, sendmsg);
}

hope that helps.

douzhao6584
douzhao6584 例如,我在时间上放了60,在数量上放了5,但它等了60秒然后只发送了5个,每60秒发送1个文本,直到发送了5个文本为止
5 年多之前 回复
dqp4933
dqp4933 我把你的代码放进去了,我相信它现在等到时间,然后在那之后它会立即发送数量。 我不确定我是否清楚,但目标是它每次发送一定数量的文本,每次1个文本
5 年多之前 回复
doushao6874
doushao6874 只需使用我提供的代码更改整个代码,其中包括带有本地内部变量的范围函数(_provider,_message等)。 - 除此之外,你不需要改变任何东西。
5 年多之前 回复
dou7851
dou7851 1.当你说改变我的代码时,你的意思是只有for循环,而不是整个事情对吗? 我不太清楚你为什么把_放在事物面前?
5 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐