簡體   English   中英

.then() 不會等到異步 function 解析 promise?

[英].then() doesn't wait till async function resolves promise?

我有兩個功能。 首先包含 jQuery.get().done() ,它的返回值在 done() 回調 function 內部,如下所示。 (我不知道在這里使用 jQuery 是否重要)

我可能不明白,但我的功能與第一個 w3 示例中的功能相似: https://www.w3schools.com/js/js_async.asp

async function A(){     
  jQuery.get("example.com").done(function(result){
    if (result.indexOf("Example")){
      console.log("sucess");
      return 1;
    } else {
      console.log("Fail");
      return -1;
    }
  })
}

function B(){
  A().then(function(result){
    console.log("Res:" + result);
  })
}

B();

但是 output 是:

 Res:undefined // here some time passes for A() to complete. succes

所以我不明白為什么。then() 不等待 function A() 完成並解決 promise,而是在尚未定義結果時立即起作用?

使用實際的 Promise(jQuery 支持)寫得更好, await如下:

async function A() {
    const result = await jQuery.get("example.com");
    if (result.indexOf("Example") !== -1) {
        console.log("sucess");
        return 1;
    } else {
        console.log("Fail");
        return -1;
    }
}

筆記:

  1. 停止使用 jQuery 的.done() 這是非標准的。 使用.then()await
  2. 不要將await.done().then() () 混合使用。 使用一個 model 或另一個。
  3. 不需要res中間變量。 當您擺脫.done()時,您可以直接返回該值。
  4. 注意, .indexOf()不返回 boolean。 如果未找到,則返回 -1,如果找到,則返回 position 的索引。 最好不要將其返回值視為 boolean。

這並不是真正的 jQuery 事情。 一般來說,它只是異步 JS。 不確定您是否真的需要 the.done() 部分,因為您使用的是 Promise。

但無論如何,你有兩個基本問題。

  1. 您需要返回 function A 內部的東西,而不是.done()內部。 所以你可以返回jQuery.get()

  2. 在 function B 中,您要等待 function A 完成,然后再點擊 .then .then()塊。 這意味着 function B 也是異步的。 (在下面的簡單示例中,您可以省略 function A 上的async關鍵字。)您需要將 function B 聲明為async ,然后await ZC1C425268E68385D14AB5074C17A9A9 完成。

function A() {
  return jQuery.get("example.com").done(function(result) {
    if (result.indexOf("Example")) {
      console.log("sucess", result);
    } else {
      console.log("Fail", result);
    }
  });
}

async function B() {
  await A().then(function(result) {
    console.log("Res:");
    // moved to a separate console log, otherwise dev tools might print
    // a lot of [objectObject] instead of the actual result
    console.log(result);
  })
}

B();

如果你想在 function A 內部做其他事情,然后最終返回結果,你可以玩一些更像

async function A() {
  const response = await jQuery.get('example.com');
  // more stuff…
  return response;
}

我通過將 return 語句從 the.done(function(){}) 移到外部並在 jQuery 鏈之前添加 await 來修復它。 而不是在該回調 function 中返回值,現在我只將值傳遞給變量,該變量稍后在該回調 function 之外返回。

async function A(){     
 let res = 0; 
  await jQuery.get("example.com").done(function(result){ //await was added
    if (result.indexOf("Example")){
      console.log("sucess");
      res = 1; // value is passed to variable, which is returned as result outside this callback function
    } else {
      console.log("Fail");
      res = -1;
    }
  })
  return res; // return statement is outside the callback function
}

function B(){
  A().then(function(result){
    console.log("Res:" + result);
  })
}

B();

我想問題是,正如@cjl750 的回答所說,回調 function 中的 return 語句沒有被“視為”為 function 的“真正的返回語句”。 所以 function B() 可能將 function A() 視為 function,它不會返回任何內容。


編輯

我已經使用 $.Deferred() object 重寫了代碼。 現在應該好多了。 Await 現在移至 function B(),它不再等待 jQuery 鏈。

function A(){     
 var dfd = $.Deferred();
 jQuery.get("google.com").then(function(result){ 
    if (result.indexOf("Example")){
      console.log("sucess");
      dfd.resolve(1); 
    } else {
      console.log("Fail");
      dfd.resolve(-1); 
    }
  })
  return dfd.promise();
}

async function B(){
  await A().then(function(result){
    console.log("Res:" + result);
  })
}

B();

暫無
暫無

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

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