簡體   English   中英

Javascript中如何執行異步代碼

[英]How to execute asynchronous code in Javascript

我查看了關於異步函數的 MDN web 文檔文章,由於某種原因它對我不起作用

這是我的代碼

function createObject() {
        try {
      console.log("Processing POST Loan.");
    
        var data = {
            "value1" : 1288,
            "value2" : [{
                "value3" : 3833,
                    "value4": [{
                        "value5": new Date()
                    }]
            }]      
        }
        var auth = Buffer.from("login:pass").toString('base64')
        const res = request("http://url.com/resource", {
          method: "POST",
          headers: {
            'Content-Type': 'application/json',
            'Authorization': "Basic "+auth
          },
          body: JSON.stringify(data)
      }, function(error, response, body){
            //console.log(response + ' '+body)
      })
      var response = res.body.id;
      return response
   }
   catch(err) { 

    throw err
    }
}

async function uploadReport() {
    console.log('cerate object')
    var objectId = await createObject();
    console.log('object = '+objectId)
}
 uploadReport() 

完全按照文章中的描述。 但是當我運行我的腳本時,我得到了這個結果:

cerate object
Processing POST Loan.
'data {"value1":1288,"value2":[{"value3":3833,"value4":[{"value5":"2021-10-05T09:45:46.126Z"}]}]}'
'auth '
object = undefined

然后幾秒鍾沒有任何反應,執行停止。 Http 請求工作正常,並且在我運行腳本時正在創建對象,但我沒有收到任何響應(此 API 應返回自動生成的 object ID)。 我在這里做錯了什么?

讓我們從頭開始,因為你看起來有點困惑。

您想要做的是從callback類型 function(“請求”)進行異步調用。 為此,您必須使用Promise

因此,您的createObject function必須返回新的request object,或必須聲明為async function8。當您的 Promise 解析時調用。


function createObject() {
    return new Promise((resolve, reject) => {
        try {
             console.log("Processing POST Loan.");
    
             var data = {
                "value1" : 1288,
                "value2" : [{
                    "value3" : 3833,
                        "value4": [{
                            "value5": new Date()
                        }]
                }]      
             }
           var auth = Buffer.from("login:pass").toString('base64')
           const res = request("http://url.com/resource", {
               method: "POST",
               headers: {
                   'Content-Type': 'application/json',
                   'Authorization': "Basic "+auth
               },
               body: JSON.stringify(data)
           }, function(error, response, body){
               if(error) reject(error);
               resolve({ response, body });
           });
       }
       catch(err) { 
           reject(err);//the promise is rejected
       }
    });
}

async function uploadReport() {
    console.log('cerate object')
    const res = await createObject();
    //in res you get 'response' and 'body' where you have the result of your API.
    //it's up to you to adapt this to what you want
    console.log(res);
}

uploadReport() 

我假設您是 JS 編程的新手,並且您似乎對異步代碼的執行流程如何工作缺乏了解。

在 JS 中,異步代碼在 promises 中工作。 Promises是 JS 表示代碼的方式,最終會產生一個值(或 void,但它們是一樣的)。

所以現在我們需要一種方法來控制執行流程。 這意味着,我們應該能夠在獲得該結果執行依賴於該結果的代碼。 或者換句話說,我們應該等待 promise 解析,然后執行依賴它的代碼。

輸入回調。 回調是在 JS 中完成的方式(在async/await出現之前,但我們不要超越自己)。 由於函數首先是 class JS 中的公民,我們可以聲明它們並將它們作為 function arguments 傳遞。因此,在這些術語中,回調是在 promise 給我們它的結果之后應該執行的代碼。

談到回調,我個人看到了兩種處理回調的方法。

第一種方法 function 期望這樣的回調作為參數。 通常(但不一定是這樣)第一個 arguments 是執行任務所需的實際 arguments ,最后一個是回調:任務完成后要做什么。 例子:

// A function that receives an `arguments` object and a `callback` function.
// Observe 
function doSomethingAsynchronous(arguments, callback) {
  const a = arguments.a
  const b = arguments.b

  const result = a + b //this is not asynchronous, only to illustrate.

  callback(result)
}

您可以像這樣使用這個 function:

doSomethingAsynchronous({a:2, b:3}, (result)=>{
  console.log(`The result was ${result}`)
})

請注意doSomethingAsynchronous如何不返回任何內容; 執行流指向回調。

第二種方法可能是 function,它返回一個實際的 Promise。Promise 有一個then()方法和一個catch()方法。 這些用於在解析 Promise 之后鏈接更多代碼:

function iReturnAPromise(arguments) {
  return new Promise((resolve, reject) => {
    const result = arguments.a + arguments.b;
    resolve(result);

  })
}

您可以通過這樣做來管理執行流程:

const promiseOfTheResult = iReturnAPromise({a: 2, b:2})

promiseOfTheResult.then((result) => {console.log(result)})

// You'll never see it like that. You'll always see:

iReturnAPromise({a:2, b:3}).then((result) => {console.log(result)})

最后但同樣重要的是, async/await簡化了 promises 的使用。 使用 async await,您將聲明iReturnAPromise同樣,但您可以像這樣使用它;

const result = await iReturnAPromise({a:1, b:2})

console.log(result)

請注意最后一個方法如何使代碼保持一致並避免回調地獄。 還要注意不返回 promise 的函數是如何不能等待的,它們首先必須被“承諾”:也就是說,將它們包裝在 promise 中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM