Javascript中的异步阻塞请求:从异步函数返回值

时间:2018-03-22 10:09:52

标签: javascript typescript async-await

我正在使用异步并等待实现此目的。以下是我的代码,它按预期工作。

function publish() {    
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve("SUCCESS");
    }, 3000);  
  });
}
var res;
async function sendRequest() {
  console.log("START\n");
  res = await publish();
  console.log("RESULT: ",res)
  console.log("END\n");
}
sendRequest();

以下是输出:

START

SUCCESS

END

但我想要实现的目的如下:

function publish() {    
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve("SUCCESS");
    }, 3000);    
  });
}
var res;
async function sendRequest() {
  console.log("START\n");
  res = await publish();
  console.log("RESULT: ",res)
  console.log("END\n");
  return res;
}

/**
 * EXPECTED BEHAVIOUR
 * Assume this function is an action of a controller class
 * It will call sendRequest() and waits for its response.
 * Once received, it will return that response to the client who called the action.
 */
function controller () {
  return sendRequest();
}    
/**
 * ACTUAL BEHAVIOUR: It will out put following
 * START
 * FINAL RESPONSE Promise { <pending> } 
 * RESULT:  SUCCESS
 * SEND
 */
var endResult = controller (); 
console.log("FINAL RESPONSE",endResult);

所以我的问题是为什么在FINAL RESPONSE Promise { <pending> }之前打印RESULT: SUCCESS

  • 如果这是async await的行为,我怎样才能实现我的目标 预期的行为。我不想在我的控制器中使用then()
  • 是否可以使用while循环?可能是我错了。这会很棒 如果有人可以指导我。

3 个答案:

答案 0 :(得分:1)

async..await是承诺的语法糖,提供类似同步的控制流。 async函数只是一个总是返回一个promise的函数。每个async函数都可以重写为常规函数,显式使用Promise并返回一个promise。

  

我不想在我的控制器中使用then()。

然后controller可以选择async,调用它的函数应该是async

let endResult = await controller();

否则控制流会产生this infamous problem

  

是否可以使用while循环?

while和其他循环语句支持async..await。只要在async函数内执行循环,它就是:

while (condition) {
    let endResult = await controller();
    // ...
}

最好使用async..await来达到这个目的,因为desugared版本不那么吸引人并且难以理解:

let resultsPromise = Promise.resolve();

while (condition) {
    resultsPromise = resultsPromise
    .then(() => controller())
    .then(endResult => {
        // ...
    });
}

resultsPromise.then(() => { /* loop has finished */ })

答案 1 :(得分:0)

您必须将async函数作为Promise来处理,例如:

function controller () {
  return sendRequest()
}

controller().then(endResult => console.log("FINAL RESPONSE",endResult)) 

答案 2 :(得分:0)

您可以添加包装函数

// Code goes here
(async function(){

function publish() {

  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve("SUCCESS");
    }, 3000);

  });
}

var res;

async function sendRequest() {
  console.log("START\n");
  res = await publish();
  console.log("RESULT: ",res)
  console.log("END\n");
  return res;
}

/**
 * EXPECTED BEHAVIOUR
 * Assume this function is an action of a controller class
 * It will call sendRequest() and waits for its response.
 * Once received, it will return that response to the client who called the action.
 */
function controller () {
  return sendRequest();
}

/**
 * ACTUAL BEHAVIOUR: It will out put following
 * START
 * FINAL RESPONSE Promise { <pending> } 
 * RESULT:  SUCCESS
 * SEND
 */
var endResult = await  controller (); 
console.log("FINAL RESPONSE",endResult);
}())