第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

如何從異步調(diào)用返回響應(yīng)?

如何從異步調(diào)用返回響應(yīng)?

我有一個(gè)foo發(fā)出Ajax請(qǐng)求的函數(shù)。我怎樣才能從中回復(fù)foo?我嘗試從success回調(diào)中返回值,并將響應(yīng)分配給函數(shù)內(nèi)部的局部變量并返回該變量,但這些方法都沒(méi)有實(shí)際返回響應(yīng)。function foo() {     var result;     $.ajax({         url: '...',         success: function(response) {             result = response;             // return response; // <- I tried that one as well         }     });     return result;}var result = foo(); // It always ends up being `undefined`.
查看完整描述

6 回答

?
鳳凰求蠱

TA貢獻(xiàn)1825條經(jīng)驗(yàn) 獲得超4個(gè)贊

如果您沒(méi)有在代碼中使用jQuery,那么這個(gè)答案就適合您

你的代碼應(yīng)該是這樣的:

function foo() {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();
    return httpRequest.responseText;}var result = foo(); // always ends up being 'undefined'

Felix Kling為使用jQuery for AJAX的人寫(xiě)了一個(gè)很好的答案,我決定為那些沒(méi)有使用jQuery的人提供替代方案。

你面對(duì)的是什么

這是另一個(gè)答案的“問(wèn)題解釋”的簡(jiǎn)短摘要,如果您在閱讀本文后不確定,請(qǐng)閱讀。

AJAX中的A代表異步。這意味著發(fā)送請(qǐng)求(或者更確切地說(shuō)是接收響應(yīng))將從正常執(zhí)行流程中取出。在您的示例中,.send立即返回,并且在return result;您作為success回調(diào)傳遞的函數(shù)被調(diào)用之前執(zhí)行下一個(gè)語(yǔ)句。

這意味著當(dāng)您返回時(shí),您定義的偵聽(tīng)器尚未執(zhí)行,這意味著您返回的值尚未定義。

這是一個(gè)簡(jiǎn)單的比喻

function getFive(){ 
    var a;
    setTimeout(function(){
         a=5;
    },10);
    return a;}

(小提琴)

a返回的值是undefined因?yàn)?code>a=5零件尚未執(zhí)行。AJAX就像這樣,你在服務(wù)器有機(jī)會(huì)告訴瀏覽器這個(gè)值是什么之前返回值。

一個(gè)可能的解決這個(gè)問(wèn)題的代碼重新活躍,告訴你的程序在計(jì)算完成后做什么。

function onComplete(a){ // When the code completes, do this
    alert(a);}function getFive(whenDone){ 
    var a;
    setTimeout(function(){
         a=5;
         whenDone(a);
    },10);}

這稱為CPS?;旧?,我們?cè)?code>getFive完成時(shí)傳遞一個(gè)動(dòng)作來(lái)執(zhí)行,我們告訴我們的代碼在事件完成時(shí)如何反應(yīng)(比如我們的AJAX調(diào)用,或者在這種情況下是超時(shí))。

用法是:

getFive(onComplete);

哪個(gè)應(yīng)警告“5”到屏幕。(小提琴)

可能的解決方案

基本上有兩種解決方法:

  1. 使AJAX調(diào)用同步(讓我們稱之為SJAX)。

  2. 重構(gòu)代碼以使用回調(diào)正常工作。

1.同步AJAX - 不要這樣做!!

至于同步AJAX,不要這樣做!費(fèi)利克斯的回答提出了一些令人信服的論據(jù),說(shuō)明為什么這是一個(gè)壞主意??偠灾?,它會(huì)凍結(jié)用戶的瀏覽器,直到服務(wù)器返回響應(yīng)并創(chuàng)建非常糟糕的用戶體驗(yàn)。以下是MDN對(duì)于其原因的另一個(gè)簡(jiǎn)短摘要:

XMLHttpRequest支持同步和異步通信。但是,一般而言,出于性能原因,異步請(qǐng)求應(yīng)優(yōu)先于同步請(qǐng)求。

簡(jiǎn)而言之,同步請(qǐng)求會(huì)阻止代碼的執(zhí)行......這可能會(huì)導(dǎo)致嚴(yán)重的問(wèn)題......

如果你必須這樣做,你可以傳遞一個(gè)標(biāo)志:這是如何:

var request = new XMLHttpRequest();request.open('GET', 'yourURL', false);  
// `false` makes the request synchronousrequest.send(null);if (request.status === 200) {// That's HTTP for 'ok'
  console.log(request.responseText);}

2.重組代碼

讓你的函數(shù)接受回調(diào)。在示例foo中,可以使代碼接受回調(diào)。我們將告訴我們的代碼在完成時(shí)如何反應(yīng)foo。

所以:

var result = foo();// code that depends on `result` goes here

變?yōu)椋?/p>

foo(function(result) {
    // code that depends on `result`});

這里我們傳遞了一個(gè)匿名函數(shù),但我們可以輕松地將引用傳遞給現(xiàn)有函數(shù),使其看起來(lái)像:

function myHandler(result) {
    // code that depends on `result`}foo(myHandler);

有關(guān)如何完成此類(lèi)回調(diào)設(shè)計(jì)的更多詳細(xì)信息,請(qǐng)查看Felix的答案。

現(xiàn)在,讓我們定義foo自己采取相應(yīng)的行動(dòng)

function foo(callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onload = function(){ // when the request is loaded
       callback(httpRequest.responseText);// we're calling our method
    };
    httpRequest.open('GET', "/echo/json");
    httpRequest.send();}

(小提琴)

我們現(xiàn)在已經(jīng)讓我們的foo函數(shù)接受了一個(gè)在AJAX成功完成時(shí)運(yùn)行的動(dòng)作,我們可以通過(guò)檢查響應(yīng)狀態(tài)是否為200并進(jìn)行相應(yīng)的操作來(lái)進(jìn)一步擴(kuò)展它(創(chuàng)建一個(gè)失敗處理程序等)。有效解決我們的問(wèn)題。

如果您仍然很難理解這一點(diǎn),請(qǐng)閱讀 MDN 的AJAX入門(mén)指南。


查看完整回答
反對(duì) 回復(fù) 2019-05-20
?
慕姐4208626

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超7個(gè)贊

XMLHttpRequest 2(首先閱讀 Benjamin Gruenbaum Felix Kling的答案)

如果你不使用jQuery并想要一個(gè)很好的簡(jiǎn)短的XMLHttpRequest 2,它適用于現(xiàn)代瀏覽器,也適用于移動(dòng)瀏覽器,我建議用這種方式:

function ajax(a, b, c){ // URL, callback, just a placeholder
  c = new XMLHttpRequest;
  c.open('GET', a);
  c.onload = b;
  c.send()}

如你看到的:

  1. 它比列出的所有其他功能都短。

  2. 回調(diào)是直接設(shè)置的(因此沒(méi)有額外的不必要的閉包)。

  3. 它使用新的onload(因此您不必檢查readystate && status)

  4. 還有其他一些我不記得的情況會(huì)讓XMLHttpRequest 1變得煩人。

有兩種方法可以獲得此Ajax調(diào)用的響應(yīng)(三種使用XMLHttpRequest var名稱):

最簡(jiǎn)單的:

this.response

或者,如果由于某種原因你bind()回調(diào)到一個(gè)類(lèi):

e.target.response

例:

function callback(e){
  console.log(this.response);}ajax('URL', callback);

或者(上面的一個(gè)是更好的匿名函數(shù)總是一個(gè)問(wèn)題):

ajax('URL', function(e){console.log(this.response)});

沒(méi)什么比這更容易

現(xiàn)在有些人可能會(huì)說(shuō)最好使用onreadystatechange或甚至XMLHttpRequest變量名。那是錯(cuò)的。

查看XMLHttpRequest高級(jí)功能

它支持所有*現(xiàn)代瀏覽器。我可以確認(rèn),因?yàn)槲沂褂眠@種方法,因?yàn)閄MLHttpRequest 2存在。在我使用的所有瀏覽器上,我從未遇到任何類(lèi)型的問(wèn)題。

onreadystatechange僅在您希望獲取狀態(tài)2的標(biāo)頭時(shí)才有用。

使用XMLHttpRequest變量名是另一個(gè)大錯(cuò)誤,因?yàn)槟阈枰趏nload / oreadystatechange閉包內(nèi)執(zhí)行回調(diào),否則你就丟失了它。


現(xiàn)在,如果您想使用post和FormData更復(fù)雜的東西,您可以輕松擴(kuò)展此功能:

function x(a, b, e, d, c){ // URL, callback, method, formdata or {key:val},placeholder
  c = new XMLHttpRequest;
  c.open(e||'get', a);
  c.onload = b;
  c.send(d||null)}

再一次......這是一個(gè)非常短的功能,但它確實(shí)得到和發(fā)布。

用法示例:

x(url, callback); // By default it's get so no need to setx(url, callback, 'post', {'key': 'val'}); // No need to set post data

或者傳遞一個(gè)完整的表單元素(document.getElementsByTagName('form')[0]):

var fd = new FormData(form);x(url, callback, 'post', fd);

或者設(shè)置一些自定義值:

var fd = new FormData();fd.append('key', 'val')x(url, callback, 'post', fd);

如你所見(jiàn),我沒(méi)有實(shí)現(xiàn)同步...這是一件壞事。

話雖如此......為什么不這么簡(jiǎn)單呢?


正如評(píng)論中所提到的,使用error && synchronous確實(shí)完全打破了答案的要點(diǎn)。哪個(gè)是以正確方式使用Ajax的簡(jiǎn)短方法?

錯(cuò)誤處理程序

function x(a, b, e, d, c){ // URL, callback, method, formdata or {key:val}, placeholder
  c = new XMLHttpRequest;
  c.open(e||'get', a);
  c.onload = b;
  c.onerror = error;
  c.send(d||null)}function error(e){
  console.log('--Error--', this.type);
  console.log('this: ', this);
  console.log('Event: ', e)}function displayAjax(e){
  console.log(e, this);}x('WRONGURL', displayAjax);

在上面的腳本中,您有一個(gè)靜態(tài)定義的錯(cuò)誤處理程序,因此它不會(huì)危及該功能。錯(cuò)誤處理程序也可用于其他功能。

但要真正解決錯(cuò)誤,唯一的方法是寫(xiě)一個(gè)錯(cuò)誤的URL,在這種情況下每個(gè)瀏覽器都會(huì)拋出一個(gè)錯(cuò)誤。

如果您設(shè)置自定義標(biāo)頭,將responseType設(shè)置為blob數(shù)組緩沖區(qū)或其他任何內(nèi)容,則錯(cuò)誤處理程序可能很有用...

即使你傳遞'POSTAPAPAP'作為方法它也不會(huì)拋出錯(cuò)誤。

即使你將'fdggdgilfdghfldj'作為formdata傳遞它也不會(huì)拋出錯(cuò)誤。

在第一種情況下,錯(cuò)誤在displayAjax()under this.statusTextas中Method not Allowed。

在第二種情況下,它只是起作用。如果您傳遞了正確的帖子數(shù)據(jù),則必須在服務(wù)器端進(jìn)行檢查。

跨域不允許自動(dòng)拋出錯(cuò)誤。

在錯(cuò)誤響應(yīng)中,沒(méi)有錯(cuò)誤代碼。

只有this.type哪個(gè)被設(shè)置為錯(cuò)誤。

如果您完全無(wú)法控制錯(cuò)誤,為什么要添加錯(cuò)誤處理程序?大多數(shù)錯(cuò)誤都在回調(diào)函數(shù)中返回displayAjax()。

因此:如果您能夠正確復(fù)制和粘貼URL,則無(wú)需進(jìn)行錯(cuò)誤檢查。;)

PS:作為我寫(xiě)的第一個(gè)測(cè)試x('x',displayAjax)......,它完全得到了回應(yīng)...... ??? 所以我檢查了HTML所在的文件夾,并且有一個(gè)名為'x.xml'的文件。因此,即使您忘記了文件的擴(kuò)展名,XMLHttpRequest 2也會(huì)找到它。我好意思


同步讀取文件

不要那樣做。

如果你想阻止瀏覽器一段時(shí)間加載一個(gè)漂亮的大.txt文件同步。

function omg(a, c){ // URL
  c = new XMLHttpRequest;
  c.open('GET', a, true);
  c.send();
  return c; // Or c.response}

現(xiàn)在你可以做到

 var res = omg('thisIsGonnaBlockThePage.txt');

沒(méi)有其他方法可以以非異步方式執(zhí)行此操作。(是的,使用setTimeout循環(huán)......但是認(rèn)真嗎?)

另一點(diǎn)是......如果你使用API或只是你自己的列表文件或者你總是為每個(gè)請(qǐng)求使用不同的函數(shù)...

只有當(dāng)你有一個(gè)頁(yè)面,你總是加載相同的XML / JSON或任何你只需要一個(gè)函數(shù)。在這種情況下,修改一點(diǎn)Ajax函數(shù)并用您的特殊函數(shù)替換b。


以上功能僅供基本使用。

如果你想擴(kuò)展功能......

是的你可以。

我使用了很多API,我在每個(gè)HTML頁(yè)面中集成的第一個(gè)函數(shù)之一是這個(gè)答案中的第一個(gè)Ajax函數(shù),只有GET ...

但是你可以用XMLHttpRequest 2做很多事情:

我創(chuàng)建了一個(gè)下載管理器(使用范圍,包括簡(jiǎn)歷,文件讀取器,文件系統(tǒng)),使用畫(huà)布的各種圖像調(diào)整器轉(zhuǎn)換器,使用base64images填充Web SQL數(shù)據(jù)庫(kù)等等......但在這些情況下,您應(yīng)該只創(chuàng)建一個(gè)函數(shù)目的...有時(shí)你需要一個(gè)blob,數(shù)組緩沖區(qū),你可以設(shè)置標(biāo)題,覆蓋mimetype,還有更多......

但這里的問(wèn)題是如何返回Ajax響應(yīng)...(我添加了一個(gè)簡(jiǎn)單的方法。)


查看完整回答
反對(duì) 回復(fù) 2019-05-20
?
慕運(yùn)維8079593

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超5個(gè)贊

您正在使用Ajax。我們的想法不是讓它返回任何東西,而是將數(shù)據(jù)交給稱為回調(diào)函數(shù)的東西,該函數(shù)處理數(shù)據(jù)。

那是:

function handleData( responseData ) {

    // Do what you want with the data
    console.log(responseData);}$.ajax({
    url: "hi.php",
    ...
    success: function ( data, status, XHR ) {
        handleData(data);
    }});

在提交處理程序中返回任何內(nèi)容都不會(huì)執(zhí)行任何操作。您必須切換數(shù)據(jù),或者直接在成功函數(shù)內(nèi)執(zhí)行您想要的操作。


查看完整回答
反對(duì) 回復(fù) 2019-05-20
?
弒天下

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超8個(gè)贊

最簡(jiǎn)單的解決方案是創(chuàng)建一個(gè)JavaScript函數(shù)并調(diào)用它來(lái)進(jìn)行Ajax success回調(diào)。

function callServerAsync(){
    $.ajax({
        url: '...',
        success: function(response) {

            successCallback(response);
        }
    });}function successCallback(responseObj){
    // Do something like read the response and show data
    alert(JSON.stringify(responseObj)); // Only applicable to JSON response}function foo(callback) {

    $.ajax({
        url: '...',
        success: function(response) {
           return callback(null, response);
        }
    });}var result = foo(function(err, result){
          if (!err)
           console.log(result);    });


查看完整回答
反對(duì) 回復(fù) 2019-05-20
  • 6 回答
  • 0 關(guān)注
  • 2168 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)