jQuery ตัวอย่างการสำรวจอย่างง่าย


105

ฉันกำลังเรียนรู้ jQuery และฉันกำลังพยายามหาตัวอย่างโค้ดง่ายๆที่จะสำรวจ API สำหรับเงื่อนไข (เช่นขอหน้าเว็บทุกๆสองสามวินาทีและประมวลผลผลลัพธ์)

ฉันคุ้นเคยกับวิธีการทำ AJAX ใน jQuery ดูเหมือนว่าฉันจะหาวิธีที่ "เหมาะสม" ในการทำให้มันทำงานบน "ตัวจับเวลา" ไม่ได้

คำตอบ:


140
function doPoll(){
    $.post('ajax/test.html', function(data) {
        alert(data);  // process results here
        setTimeout(doPoll,5000);
    });
}

4
บางคนได้ใช้และบางส่วนได้นำมาใช้setTimeout setIntervalทำไมคนหนึ่งถึงชอบคนอื่น?
Mike

36
setinterval จะทำการโทร ajax ทุกๆ 5 วินาทีไม่ว่าจะเกิดอะไรขึ้น วิธีที่เขียนไว้ (ซึ่งฉันเชื่อว่าเป็นแนวทางปฏิบัติที่ดี) จะรอผลลัพธ์จากนั้นจึงขอ ajax อีก 5 วินาทีในภายหลัง มีหลายครั้งที่ฉันจะใช้ setinterval แต่นี่ไม่ใช่หนึ่งในนั้น เราไม่ควรส่งคำขอใหม่ใด ๆ จนกว่าเราจะได้รับผลลัพธ์จากคำขอล่าสุด
Johnny Craig

108
โปรดระวังว่ารหัสที่แนะนำจะหยุดการสำรวจหากคำขอเดียวล้มเหลว ในสถานการณ์ทั่วไปคุณอาจต้องการดำเนินการสำรวจต่อไป ฉันจะไม่ได้setTimeoutอยู่ในการจัดการความสำเร็จแต่แทนที่จะห่วงโซ่โทร Ajax กับjQuery เสมอ ดังนี้: $.post('ajax/test.html') .done(function(data) { /* process */ }) .always(function() { setTimeout(doPoll, 5000); });
MårtenWikström

6
ไม่มีการเพิ่มประสิทธิภาพการโทรหาง สิ่งนี้จะเพิ่มสแต็กการเรียกฟังก์ชันไปเรื่อย ๆ แนะนำให้ใช้รูปแบบแทรมโพลีน
Boopathi Rajaa

8
@BoopathiRajaa โปรดยกตัวอย่างรูปแบบแทรมโพลีนดังกล่าว
santa

61

นี่คือบทความที่เป็นประโยชน์เกี่ยวกับการสำรวจความคิดเห็นแบบยาว (คำขอ HTTP แบบยาว) โดยใช้ jQuery ข้อมูลโค้ดที่ได้มาจากบทความนี้:

(function poll() {
    setTimeout(function() {
        $.ajax({
            url: "/server/api/function",
            type: "GET",
            success: function(data) {
                console.log("polling");
            },
            dataType: "json",
            complete: poll,
            timeout: 2000
        })
    }, 5000);
})();

การดำเนินการนี้จะทำให้คำขอถัดไปหลังจากคำขอ ajax เสร็จสมบูรณ์

รูปแบบด้านบนที่จะดำเนินการทันทีในครั้งแรกที่เรียกก่อนที่จะปฏิบัติตามช่วงเวลารอ / หมดเวลา

(function poll() {
    $.ajax({
        url: "/server/api/function",
        type: "GET",
        success: function(data) {
            console.log("polling");
        },
        dataType: "json",
        complete: setTimeout(function() {poll()}, 5000),
        timeout: 2000
    })
})();

มีวิธียกเลิกการเลือกตั้งหรือส่งสัญญาณให้หยุดหรือไม่
Tal

ฉันจะล้างการหมดเวลาได้อย่างไรหากได้รับผลลัพธ์ที่คาดหวังจากเซิร์ฟเวอร์
abhishek77 ใน

คุณสามารถล้างการหมดเวลาได้ดังตัวอย่างต่อไปนี้let is_success = false; (function poll() { let timeout = setTimeout(function() { $.ajax({ url: resp.location, type: "GET", success: function(data) { if(YOUR_CONDITION) { is_success=true; } }, dataType: "json", complete: poll, timeout: 2000 }) }, 5000); if(is_success) { console.log("ending poll"); window.clearTimeout(timeout); } })();
Marius

2
อย่าคลิกที่ลิงค์ techoctave.com ด้านบน พยายามทำสิ่งที่น่ารังเกียจทุกประเภท
Siddharth Ram

13

จาก ES6

var co = require('co');
var $ = require('jQuery');

// because jquery doesn't support Promises/A+ spec
function ajax(opts) {
  return new Promise(function(resolve, reject) {
    $.extend(opts, {
      success: resolve,
      error: reject
    });
    $.ajax(opts);
  }
}

var poll = function() {
  co(function *() {
    return yield ajax({
      url: '/my-api',
      type: 'json',
      method: 'post'
    });
  }).then(function(response) {
    console.log(response);
  }).catch(function(err) {
    console.log(err);
  });
};

setInterval(poll, 5000);
  • ไม่ใช้การเรียกซ้ำ (ฟังก์ชัน stack ไม่ได้รับผลกระทบ)
  • ไม่ต้องทนทุกข์ทรมานจากการที่ setTimeout-recursion ต้องได้รับการปรับให้เหมาะสมกับ tail-call

ยินดีที่ได้เห็นโซลูชัน ES6!
PHearst

อะไรทำให้มันเป็นโซลูชัน ES6 Boopathi Rajaa, setInterval ()?
Halil



2

jQuery.Deferred ()สามารถลดความซับซ้อนในการจัดการลำดับอะซิงโครนัสและการจัดการข้อผิดพลาด

polling_active = true // set false to interrupt polling

function initiate_polling()
    {
    $.Deferred().resolve() // optional boilerplate providing the initial 'then()'
    .then( () => $.Deferred( d=>setTimeout(()=>d.resolve(),5000) ) ) // sleep
    .then( () => $.get('/my-api') ) // initiate AJAX
    .then( response =>
        {
        if ( JSON.parse(response).my_result == my_target ) polling_active = false
        if ( ...unhappy... ) return $.Deferred().reject("unhappy") // abort
        if ( polling_active ) initiate_polling() // iterative recursion
        })
    .fail( r => { polling_active=false, alert('failed: '+r) } ) // report errors
    }

นี่เป็นแนวทางที่สง่างาม แต่มี gotchas อยู่บ้าง ...

  • หากคุณไม่ต้องการthen()ที่จะตกผ่านทันทีโทรกลับควรกลับอีกthenableวัตถุ (อาจจะอีกDeferred) ซึ่งการนอนหลับและสายอาแจ็กซ์ทั้งทำ
  • คนอื่นอายเกินกว่าจะยอมรับ :)

คำตอบที่คล้ายกันที่: Deferred in a while loop
Brent Bradburn

ความคิดเห็น "การเรียกซ้ำซ้ำ" ของฉันอาจทำให้เข้าใจผิดเล็กน้อย ไม่มีการเรียกซ้ำที่นี่จริงเนื่องจากการเรียกแบบ "เรียกซ้ำ" เกิดขึ้นจากการโทรกลับแบบไม่ระบุตัวตน - หลังจากinitiate_pollingดำเนินการจนเสร็จสิ้น
Brent Bradburn

ในเบราว์เซอร์ล่าสุดคุณไม่จำเป็นต้องใช้ jQuery อีกต่อไป - ดูคำตอบของฉันที่นี่: stackoverflow.com/a/48728503/86967
Brent Bradburn

หมดเวลา JavaScript บริสุทธิ์:new Promise( resolve => setTimeout(resolve,1000) ).then( () => alert("done") )
Brent Bradburn

Async Recursion Is Iteration
Brent Bradburn

1

วิธีนี้:

  1. หมดเวลา
  2. การสำรวจยังทำงานหลังจากตอบสนองข้อผิดพลาด

เวอร์ชันขั้นต่ำของ jQuery คือ 1.12

$(document).ready(function () {
  function poll () {
    $.get({
      url: '/api/stream/',
      success: function (data) {
        console.log(data)
      },
      timeout: 10000                    // == 10 seconds timeout
    }).always(function () {
      setTimeout(poll, 30000)           // == 30 seconds polling period
    })
  }

  // start polling
  poll()
})

0
(function poll() {
    setTimeout(function() {
        //
        var search = {}
        search["ssn"] = "831-33-6049";
        search["first"] = "Harve";
        search["last"] = "Veum";
        search["gender"] = "M";
        search["street"] = "5017 Ottis Tunnel Apt. 176";
        search["city"] = "Shamrock";
        search["state"] = "OK";
        search["zip"] = "74068";
        search["lat"] = "35.9124";
        search["long"] = "-96.578";
        search["city_pop"] = "111";
        search["job"] = "Higher education careers adviser";
        search["dob"] = "1995-08-14";
        search["acct_num"] = "11220423";
        search["profile"] = "millenials.json";
        search["transnum"] = "9999999";
        search["transdate"] = $("#datepicker").val();
        search["category"] = $("#category").val();
        search["amt"] = $("#amt").val();
        search["row_key"] = "831-33-6049_9999999";



        $.ajax({
            type : "POST",
            headers : {
                contentType : "application/json"
            },
            contentType : "application/json",
            url : "/stream_more",
            data : JSON.stringify(search),
            dataType : 'json',
            complete : poll,
            cache : false,
            timeout : 600000,
            success : function(data) {
                //
                //alert('jax')
                console.log("SUCCESS : ", data);
                //$("#btn-search").prop("disabled", false);
                // $('#feedback').html("");
                for (var i = 0; i < data.length; i++) {
                    //
                    $('#feedback').prepend(
                            '<tr><td>' + data[i].ssn + '</td><td>'
                                    + data[i].transdate + '</td><td>'
                                    + data[i].category + '</td><td>'
                                    + data[i].amt + '</td><td>'
                                    + data[i].purch_prob + '</td><td>'
                                    + data[i].offer + '</td></tr>').html();
                }

            },
            error : function(e) {
                //alert("error" + e);

                var json = "<h4>Ajax Response</h4><pre>" + e.responseText
                        + "</pre>";
                $('#feedback').html(json);

                console.log("ERROR : ", e);
                $("#btn-search").prop("disabled", false);

            }
        });

    }, 3000);
})();

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.