เรียกใช้ฟังก์ชัน Javascript แบบอะซิงโครนัสแบบซิงโครนัส


222

ครั้งแรกนี่เป็นกรณีที่เฉพาะเจาะจงมากในการทำผิดวิธีในการติดตั้งการโทรแบบอะซิงโครนัสใหม่ให้เป็นโค๊ดฐานซิงโครนัสมากซึ่งมีหลายพันบรรทัดในเวลาและเวลาไม่สามารถทำการเปลี่ยนแปลงได้ ถูกต้องแล้ว " มันทำให้ทุกชีวิตของฉันเจ็บปวด แต่ความจริงและอุดมคติมักไม่เข้าข่าย ฉันรู้ว่ามันแย่

ตกลงฉันจะทำมันออกไปได้อย่างไร:

function doSomething() {

  var data;

  function callBack(d) {
    data = d;
  }

  myAsynchronousCall(param1, callBack);

  // block here and return data when the callback is finished
  return data;
}

ตัวอย่าง (หรือขาดดังกล่าว) ใช้ไลบรารีและ / หรือคอมไพเลอร์ซึ่งทั้งสองอย่างนี้ไม่สามารถใช้งานได้สำหรับโซลูชันนี้ ฉันต้องการตัวอย่างที่เป็นรูปธรรมเกี่ยวกับวิธีทำให้บล็อก (เช่นไม่ออกจากฟังก์ชั่น doSomething จนกระทั่งมีการโทรกลับ) โดยไม่ต้องแช่แข็ง UI หากสิ่งนั้นเป็นไปได้ใน JS


16
ไม่สามารถทำการบล็อกเบราว์เซอร์และรอได้ พวกเขาจะไม่ทำมัน
แหลม

2
javascript dosent มีกลไกการบล็อกบนเบราว์เซอร์ส่วนใหญ่ ... คุณจะต้องสร้างการโทรกลับที่เรียกว่าเมื่อการโทรแบบ async เสร็จสิ้นเพื่อส่งคืนข้อมูล
Nadir Muzaffar

8
คุณกำลังขอวิธีบอกเบราว์เซอร์ "ฉันรู้ว่าฉันเพิ่งบอกให้คุณเรียกใช้ฟังก์ชันก่อนหน้านี้แบบอะซิงโครนัส แต่ฉันไม่ได้หมายความอย่างนั้นจริงๆ!" ทำไมคุณถึงคิดว่าเป็นไปได้
เวย์น

2
ขอบคุณ Dan สำหรับการแก้ไข ฉันไม่ได้เป็นคนหยาบคาย แต่ถ้อยคำของคุณดีกว่า
Robert C. Barth

2
@ RobertC.Barth เป็นไปได้ด้วย JavaScript เช่นกัน async ที่รอฟังก์ชั่นยังไม่ได้รับการยอมรับในมาตรฐาน แต่มีการวางแผนว่าจะอยู่ใน ES2017 ดูคำตอบของฉันด้านล่างเพื่อดูรายละเอียดเพิ่มเติม
John

คำตอบ:


135

"อย่าบอกฉันว่าฉันควรทำอย่างไร" วิธีที่ถูกต้อง "หรืออะไรก็ตาม"

ตกลง. แต่คุณควรทำในสิ่งที่ถูกต้อง ... หรืออะไรก็ตาม

"ฉันต้องการตัวอย่างที่เป็นรูปธรรมเกี่ยวกับวิธีทำให้บล็อก ... โดยไม่ต้องแช่แข็ง UI หากสิ่งนี้เป็นไปได้ใน JS"

ไม่เป็นไปไม่ได้ที่จะบล็อก JavaScript ที่กำลังรันอยู่โดยไม่ปิดกั้น UI

เนื่องจากขาดข้อมูลจึงเป็นเรื่องยากที่จะเสนอวิธีแก้ไข แต่ทางเลือกหนึ่งอาจให้ฟังก์ชั่นการโทรทำการสำรวจบางอย่างเพื่อตรวจสอบตัวแปรส่วนกลางจากนั้นตั้งค่าการโทรกลับdataเป็นโกลบอล

function doSomething() {

      // callback sets the received data to a global var
  function callBack(d) {
      window.data = d;
  }
      // start the async
  myAsynchronousCall(param1, callBack);

}

  // start the function
doSomething();

  // make sure the global is clear
window.data = null

  // start polling at an interval until the data is found at the global
var intvl = setInterval(function() {
    if (window.data) { 
        clearInterval(intvl);
        console.log(data);
    }
}, 100);

ทั้งหมดนี้ถือว่าคุณสามารถแก้ไขdoSomething()ได้ ฉันไม่รู้ว่าอยู่ในการ์ดหรือไม่

หากสามารถแก้ไขได้ฉันไม่รู้ว่าทำไมคุณไม่ส่งการโทรกลับไปdoSomething()ยังการโทรจากการโทรกลับครั้งอื่น แต่ฉันควรหยุดก่อนที่จะมีปัญหา ;)


โอ้อะไรห่า คุณยกตัวอย่างที่แนะนำว่าสามารถทำได้อย่างถูกต้องดังนั้นฉันจะแสดงวิธีแก้ปัญหานั้น ...

function doSomething( func ) {

  function callBack(d) {
    func( d );
  }

  myAsynchronousCall(param1, callBack);

}

doSomething(function(data) {
    console.log(data);
});

เนื่องจากตัวอย่างของคุณมีการโทรกลับที่ส่งผ่านไปยังการโทรแบบ async วิธีที่ถูกต้องคือการส่งผ่านฟังก์ชันdoSomething()ที่จะเรียกใช้จากการโทรกลับ

แน่นอนว่าเป็นสิ่งเดียวที่โทรกลับกำลังทำอยู่คุณจะผ่านfuncโดยตรง ...

myAsynchronousCall(param1, func);

22
ใช่ฉันรู้วิธีที่จะทำอย่างถูกต้องฉันต้องรู้วิธีการ / ถ้ามันสามารถทำได้ไม่ถูกต้องด้วยเหตุผลเฉพาะที่ระบุไว้ crux คือฉันไม่ต้องการออกจาก doSomething () จนกระทั่ง myAsynchronousCall ทำการเรียกไปยังฟังก์ชันการเรียกกลับให้เสร็จสมบูรณ์ Bleh มันไม่สามารถทำได้อย่างที่ฉันคิดว่าฉันแค่ต้องการภูมิปัญญาที่รวบรวมจาก Internets เพื่อสำรองฉัน ขอบคุณ. :-)
Robert C. Barth

2
@ RobertC.Barth: ใช่ความสงสัยของคุณถูกต้องน่าเสียดาย

เป็นฉันหรือเฉพาะรุ่น "ทำถูกต้อง" หรือไม่ คำถามรวมถึงการโทรกลับก่อนที่ควรมีบางสิ่งที่รอให้การโทร async เสร็จสิ้นซึ่งส่วนแรกของคำตอบนี้ไม่ครอบคลุม ...
ravemir

@ravemir: คำตอบระบุว่าเป็นไปไม่ได้ที่จะทำสิ่งที่เขาต้องการ นั่นเป็นส่วนสำคัญที่ต้องเข้าใจ กล่าวอีกนัยหนึ่งคุณไม่สามารถโทรแบบอะซิงโครนัสและคืนค่าโดยไม่บล็อก UI ดังนั้นทางออกแรกคือแฮ็คที่น่าเกลียดโดยใช้ตัวแปรส่วนกลางและการสำรวจเพื่อดูว่ามีการแก้ไขตัวแปรนั้นหรือไม่ รุ่นที่สองเป็นวิธีที่ถูกต้อง

1
@ Leonardo: มันเป็นฟังก์ชั่นลึกลับที่ถูกเรียกในคำถาม โดยทั่วไปจะแสดงถึงสิ่งที่เรียกใช้โค้ดแบบอะซิงโครนัสและสร้างผลลัพธ์ที่ต้องได้รับ ดังนั้นอาจเป็นเหมือนคำขอ AJAX คุณผ่านcallbackฟังก์ชั่นไปยังmyAsynchronousCallฟังก์ชั่นซึ่งจะทำสิ่ง async และจะเรียกกลับเมื่อเสร็จสมบูรณ์ นี่คือตัวอย่าง

60

ฟังก์ชั่น Asyncเป็นคุณสมบัติใน ES2017สร้างรหัส async ให้ดูตรงกันโดยใช้สัญญา (รูปแบบเฉพาะของรหัส async) และawaitคำหลัก ให้สังเกตในตัวอย่างรหัสด้านล่างคำหลักที่asyncอยู่ด้านหน้าของfunctionคำสำคัญที่แสดงถึงฟังก์ชัน async / await awaitคำหลักจะไม่ทำงานโดยไม่ต้องอยู่ในฟังก์ชั่นก่อนการแก้ไขกับasyncคำหลัก เนื่องจากปัจจุบันไม่มีข้อยกเว้นสำหรับสิ่งนี้ซึ่งหมายความว่าจะไม่มีการรอระดับสูงสุด (ระดับสูงสุดกำลังรอหมายถึงการรอคอยนอกฟังก์ชั่นใด ๆ ) แม้ว่าจะมีข้อเสนอสำหรับระดับบนสุดawait

ES2017 เป็นที่ยอมรับ (เช่นสรุป) เป็นมาตรฐานสำหรับการใช้ JavaScript ในวันที่ 27 มิถุนายน 2017 Async รอคอยอาจจะทำงานอยู่แล้วในเบราว์เซอร์ของคุณ แต่ถ้าไม่คุณยังสามารถใช้ฟังก์ชั่นการใช้งานจาวาสคริปต์ transpiler เช่นBabelหรือtraceur Chrome 55 ได้รับการสนับสนุนอย่างเต็มที่จากฟังก์ชั่น async ดังนั้นหากคุณมีเบราว์เซอร์ใหม่คุณอาจลองใช้รหัสด้านล่าง

ดูตารางความเข้ากันได้ของ kangax es2017สำหรับความเข้ากันได้ของเบราว์เซอร์

นี่คือตัวอย่างของ async ที่รอฟังก์ชั่นที่เรียกว่าdoAsyncซึ่งใช้เวลาสามวินาทีในการหยุดชั่วคราวและพิมพ์ความแตกต่างของเวลาหลังจากแต่ละหยุดจากเวลาเริ่มต้น:

function timeoutPromise (time) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(Date.now());
    }, time)
  })
}

function doSomethingAsync () {
  return timeoutPromise(1000);
}

async function doAsync () {
  var start = Date.now(), time;
  console.log(0);
  time = await doSomethingAsync();
  console.log(time - start);
  time = await doSomethingAsync();
  console.log(time - start);
  time = await doSomethingAsync();
  console.log(time - start);
}

doAsync();

เมื่อคำสำคัญที่รออยู่ถูกวางไว้ก่อนหน้ามูลค่าสัญญา (ในกรณีนี้มูลค่าสัญญาคือค่าที่ส่งคืนโดยฟังก์ชัน doSomethingAsync) คำหลักที่รอคอยจะหยุดการเรียกใช้ฟังก์ชันชั่วคราว แต่จะไม่หยุดฟังก์ชันอื่นใดและจะดำเนินการต่อ รันโค้ดอื่น ๆ จนกว่าสัญญาจะคลี่คลาย หลังจากสัญญาได้รับการแก้ไขแล้วมันจะแกะมูลค่าของสัญญาและคุณสามารถนึกถึงการรอคอยและการแสดงออกของสัญญาซึ่งตอนนี้ถูกแทนที่ด้วยมูลค่าที่ยังไม่ได้เปิด

ดังนั้นเนื่องจากรอเพียงแค่หยุดรอแล้วปล่อยค่าออกมาก่อนที่จะดำเนินการส่วนที่เหลือของบรรทัดที่คุณสามารถใช้ในการลูปและฟังก์ชั่นการโทรภายในเช่นในตัวอย่างด้านล่างซึ่งรวบรวมความแตกต่างของเวลาที่รออยู่ในอาร์เรย์และพิมพ์อาร์เรย์

function timeoutPromise (time) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(Date.now());
    }, time)
  })
}

function doSomethingAsync () {
  return timeoutPromise(1000);
}

// this calls each promise returning function one after the other
async function doAsync () {
  var response = [];
  var start = Date.now();
  // each index is a promise returning function
  var promiseFuncs= [doSomethingAsync, doSomethingAsync, doSomethingAsync];
  for(var i = 0; i < promiseFuncs.length; ++i) {
    var promiseFunc = promiseFuncs[i];
    response.push(await promiseFunc() - start);
    console.log(response);
  }
  // do something with response which is an array of values that were from resolved promises.
  return response
}

doAsync().then(function (response) {
  console.log(response)
})

ฟังก์ชัน async ส่งคืนสัญญาเพื่อให้คุณสามารถใช้เป็นสัญญากับการผูกมัดอย่างที่ฉันทำข้างบนหรือภายในฟังก์ชันรอคอยอีก async

ฟังก์ชั่นข้างต้นจะรอการตอบสนองแต่ละก่อนที่จะส่งคำขออื่นถ้าคุณต้องการที่จะส่งคำขอพร้อมกันคุณสามารถใช้Promise.all

// no change
function timeoutPromise (time) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(Date.now());
    }, time)
  })
}

// no change
function doSomethingAsync () {
  return timeoutPromise(1000);
}

// this function calls the async promise returning functions all at around the same time
async function doAsync () {
  var start = Date.now();
  // we are now using promise all to await all promises to settle
  var responses = await Promise.all([doSomethingAsync(), doSomethingAsync(), doSomethingAsync()]);
  return responses.map(x=>x-start);
}

// no change
doAsync().then(function (response) {
  console.log(response)
})

หากคำสัญญาอาจปฏิเสธคุณสามารถสรุปได้ในลอง catch หรือข้าม catch catch และปล่อยให้ข้อผิดพลาดแพร่กระจายไปยังฟังก์ชัน async / waitit catch call คุณควรระวังไม่ให้เกิดข้อผิดพลาดในสัญญาโดยเฉพาะใน Node.js ด้านล่างนี้เป็นตัวอย่างบางส่วนที่แสดงให้เห็นว่าข้อผิดพลาดทำงานอย่างไร

function timeoutReject (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      reject(new Error("OOPS well you got an error at TIMESTAMP: " + Date.now()));
    }, time)
  })
}

function doErrorAsync () {
  return timeoutReject(1000);
}

var log = (...args)=>console.log(...args);
var logErr = (...args)=>console.error(...args);

async function unpropogatedError () {
  // promise is not awaited or returned so it does not propogate the error
  doErrorAsync();
  return "finished unpropogatedError successfully";
}

unpropogatedError().then(log).catch(logErr)

async function handledError () {
  var start = Date.now();
  try {
    console.log((await doErrorAsync()) - start);
    console.log("past error");
  } catch (e) {
    console.log("in catch we handled the error");
  }
  
  return "finished handledError successfully";
}

handledError().then(log).catch(logErr)

// example of how error propogates to chained catch method
async function propogatedError () {
  var start = Date.now();
  var time = await doErrorAsync() - start;
  console.log(time - start);
  return "finished propogatedError successfully";
}

// this is what prints propogatedError's error.
propogatedError().then(log).catch(logErr)

หากคุณไปที่นี่คุณสามารถดูข้อเสนอที่เสร็จสิ้นแล้วสำหรับรุ่น ECMAScript ที่จะเกิดขึ้น

อีกทางเลือกหนึ่งสำหรับสิ่งนี้ที่สามารถใช้ได้กับ ES2015 (ES6) คือการใช้ฟังก์ชั่นพิเศษซึ่งจะหุ้มฟังก์ชั่นเครื่องกำเนิดไฟฟ้า ฟังก์ชันตัวสร้างมีคีย์เวิร์ดผลผลิตซึ่งอาจใช้ในการทำซ้ำคำสำคัญที่รออยู่พร้อมกับฟังก์ชันโดยรอบ คำหลักผลผลิตและฟังก์ชั่นเครื่องกำเนิดไฟฟ้ามีวัตถุประสงค์ทั่วไปมากขึ้นและสามารถทำสิ่งอื่น ๆ อีกมากมายแล้วเพียงแค่สิ่งที่ฟังก์ชั่น async รอทำ หากคุณต้องการเสื้อคลุมฟังก์ชั่นเครื่องกำเนิดไฟฟ้าที่สามารถนำมาใช้ในการทำซ้ำ async รอฉันจะตรวจสอบco.js โดยวิธีการที่ฟังก์ชั่นของ co เช่นเดียวกับ async กำลังรอฟังก์ชั่นคืนสัญญา จริง ๆ แล้ว ณ จุดนี้ความเข้ากันได้ของเบราว์เซอร์มีความคล้ายคลึงกันสำหรับทั้งฟังก์ชันตัวสร้างและฟังก์ชัน async ดังนั้นหากคุณต้องการให้ async รอฟังก์ชั่นการใช้งานคุณควรใช้ฟังก์ชั่น Async โดยไม่ต้องใช้ co.js

จริง ๆ แล้วการสนับสนุนเบราว์เซอร์ค่อนข้างดีสำหรับฟังก์ชั่น Async (จนถึงปี 2560) ในเบราว์เซอร์ปัจจุบันที่สำคัญทั้งหมด (Chrome, Safari และ Edge) ยกเว้น IE


2
ผมชอบคำตอบนี้
ycomp

1
เรามากันไกลแค่ไหนแล้ว :)
Derek

3
นี่เป็นคำตอบที่ดี แต่สำหรับปัญหาของผู้โพสต์ดั้งเดิมฉันคิดว่ามันจะทำให้ปัญหาเพิ่มขึ้นหนึ่งระดับ สมมติว่าเขาเปลี่ยน doSomething เป็นฟังก์ชั่น async โดยมีการรออยู่ข้างใน ตอนนี้ฟังก์ชั่นนั้นคืนสัญญาและแบบอะซิงโครนัสดังนั้นเขาจะต้องจัดการกับปัญหาเดิมอีกครั้งในสิ่งที่เรียกว่าฟังก์ชั่น
dpwrussell

1
@dpwrussell นี่เป็นความจริงมีฟังก์ชั่น async และสัญญาในฐานรหัส วิธีที่ดีที่สุดในการแก้ไขสัญญาจากที่กำลังคืบคลานเข้าสู่ทุกอย่างเป็นเพียงการเขียนเรียกกลับซิงโครมีวิธีที่จะกลับมาเป็นค่า async พร้อมกันจนกว่าคุณจะทำบางสิ่งบางอย่างมากที่แปลกและความขัดแย้งเช่นนี้ไม่มีtwitter.com/sebmarkbage/status/941214259505119232ที่ฉันทำไม่ได้ แนะนำ. ฉันจะเพิ่มการแก้ไขที่ส่วนท้ายของคำถามเพื่อให้ตอบคำถามได้อย่างเต็มที่ยิ่งขึ้นเนื่องจากถูกถามและไม่เพียง แต่ตอบคำถาม
จอห์น

มันเป็นคำตอบที่ยอดเยี่ยม +1 และทั้งหมด แต่เขียนตามที่เป็นอยู่ฉันไม่เห็นว่าสิ่งนี้มีความซับซ้อนน้อยกว่าการใช้การโทรกลับ
Altimus Prime

47

ดูที่สัญญา JQuery:

http://api.jquery.com/promise/

http://api.jquery.com/jQuery.when/

http://api.jquery.com/deferred.promise/

สร้างรหัสใหม่:

    var dfd = ใหม่ jQuery.Deferred ();


    function callBack (ข้อมูล) {
       dfd.notify (ข้อมูล);
    }

    // ทำการโทรแบบ async
    myAsynchronousCall (param1, callBack);

    function doSomething (data) {
     // ทำสิ่งต่างๆด้วยข้อมูล ...
    }

    $ .when (DFD) จากนั้น (doSomething);



3
+1 สำหรับคำตอบนี้ถูกต้อง แต่ฉันจะอัปเดตบรรทัดด้วยdfd.notify(data)ถึงdfd.resolve(data)
Jason

7
นี่เป็นกรณีของรหัสที่ให้ภาพลวงของการซิงโครนัสโดยไม่เป็นอะซิงโครนัสหรือไม่?
saurshaz

2
สัญญาเป็น IMO ที่จัดเรียงไว้อย่างดี :) ถ้าคุณต้องการการเรียกแบบอะซิงโครนัสสมมติว่ามีการเริ่มต้นวัตถุบางอย่าง
webduvet

10
คำสัญญาไม่ซิงค์
รถตู้ S

6

มีวิธีแก้ปัญหาที่ดีอย่างหนึ่งที่http://taskjs.org/

มันใช้กำเนิดซึ่งยังใหม่กับจาวาสคริปต์ ดังนั้นเบราว์เซอร์ส่วนใหญ่จึงยังไม่ได้ใช้งานในปัจจุบัน ฉันทดสอบใน Firefox และสำหรับฉันมันเป็นวิธีที่ดีในการห่อฟังก์ชั่นอะซิงโครนัส

นี่คือตัวอย่างรหัสจากโครงการ GitHub

var { Deferred } = task;

spawn(function() {
    out.innerHTML = "reading...\n";
    try {
        var d = yield read("read.html");
        alert(d.responseText.length);
    } catch (e) {
        e.stack.split(/\n/).forEach(function(line) { console.log(line) });
        console.log("");
        out.innerHTML = "error: " + e;
    }

});

function read(url, method) {
    method = method || "GET";
    var xhr = new XMLHttpRequest();
    var deferred = new Deferred();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status >= 400) {
                var e = new Error(xhr.statusText);
                e.status = xhr.status;
                deferred.reject(e);
            } else {
                deferred.resolve({
                    responseText: xhr.responseText
                });
            }
        }
    };
    xhr.open(method, url, true);
    xhr.send();
    return deferred.promise;
}

3

คุณสามารถบังคับให้ตรงกัน JavaScript ใน NodeJS จะเป็นซิงโครกับซิงค์ RPC

มันจะหยุด UI ของคุณอย่างแน่นอนดังนั้นฉันยังคงเป็นนักสังเกตการณ์เมื่อมันมาถึงว่าสิ่งที่เป็นไปได้ที่จะใช้ทางลัดที่คุณต้องใช้ เป็นไปไม่ได้ที่จะระงับเธรด One And Only ใน JavaScript แม้ว่า NodeJS จะช่วยให้คุณสามารถบล็อกได้ในบางครั้ง ไม่มีการเรียกกลับเหตุการณ์ใด ๆ แบบอะซิงโครนัสเลยจะสามารถดำเนินการได้จนกว่าสัญญาของคุณจะได้รับการแก้ไข ดังนั้นหากคุณผู้อ่านมีสถานการณ์ที่หลีกเลี่ยงไม่ได้เช่น OP (หรือในกรณีของฉันกำลังเขียนเชลล์สคริปต์ที่ได้รับการยกย่องโดยไม่มีการเรียกกลับเหตุการณ์ ฯลฯ ) อย่าทำเช่นนี้!

แต่นี่คือวิธีที่คุณสามารถทำได้:

./calling-file.js

var createClient = require('sync-rpc');
var mySynchronousCall = createClient(require.resolve('./my-asynchronous-call'), 'init data');

var param1 = 'test data'
var data = mySynchronousCall(param1);
console.log(data); // prints: received "test data" after "init data"

./my-asynchronous-call.js

function init(initData) {
  return function(param1) {
    // Return a promise here and the resulting rpc client will be synchronous
    return Promise.resolve('received "' + param1 + '" after "' + initData + '"');
  };
}
module.exports = init;

ข้อ จำกัด :

สิ่งเหล่านี้เป็นผลมาจากวิธีsync-rpcการใช้งานซึ่งเกิดจากการใช้ในทางที่ผิดrequire('child_process').spawnSync:

  1. สิ่งนี้จะไม่ทำงานในเบราว์เซอร์
  2. อาร์กิวเมนต์ของฟังก์ชั่นของคุณจะต้องต่อเนื่องกันได้ ข้อโต้แย้งของคุณจะผ่านเข้าออกJSON.stringifyดังนั้นฟังก์ชั่นและคุณสมบัติที่ไม่สามารถแจกแจงได้เช่นลูกโซ่ต้นแบบจะหายไป

1

คุณสามารถแปลงเป็นโทรกลับได้

function thirdPartyFoo(callback) {    
  callback("Hello World");    
}

function foo() {    
  var fooVariable;

  thirdPartyFoo(function(data) {
    fooVariable = data;
  });

  return fooVariable;
}

var temp = foo();  
console.log(temp);

0

สิ่งที่คุณต้องการเป็นไปได้จริงตอนนี้ หากคุณสามารถเรียกใช้รหัสแบบอะซิงโครนัสในพนักงานบริการและรหัสแบบซิงโครนัสในผู้ปฏิบัติงานเว็บคุณสามารถให้ผู้ปฏิบัติงานเว็บส่ง XHR แบบซิงโครนัสไปยังพนักงานบริการและในขณะที่ผู้ปฏิบัติงาน ด้ายจะรอ นี่ไม่ใช่วิธีการที่ยอดเยี่ยม แต่สามารถใช้งานได้


-4

ความคิดที่คุณหวังว่าจะประสบความสำเร็จนั้นสามารถเกิดขึ้นได้หากคุณปรับเปลี่ยนข้อกำหนดเล็กน้อย

รหัสด้านล่างเป็นไปได้ถ้ารันไทม์ของคุณรองรับข้อกำหนด ES6

เพิ่มเติมเกี่ยวกับฟังก์ชั่น async

async function myAsynchronousCall(param1) {
    // logic for myAsynchronous call
    return d;
}

function doSomething() {

  var data = await myAsynchronousCall(param1); //'blocks' here until the async call is finished
  return data;
}

4
Firefox SyntaxError: await is only valid in async functions and async generatorsให้ข้อผิดพลาด: ไม่ต้องพูดถึงว่าไม่ได้กำหนด param1 (และไม่ได้ใช้)
ฮาร์วีย์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.