是否可以将所有JavaScript Promise重写为使用异步等待?

时间:2018-11-03 09:05:28

标签: javascript asynchronous promise async-await

所有异步/等待代码都可以转换为Promises或其他结构。因为这就是通过babel进行的翻译。

我假设两个范例是等效的,并且所有的Promise都可以用async / await重写。这是真的?还是我需要放弃的假设。

对于一个具体的例子,我有以下代码,其中包含一个promise。 我还没有看到一种将此代码仅转换为异步/等待的方法。

对于上下文,此邮箱代码用于演示,我必须在浏览器/ JavaScript的上下文中解释Actor模型

function Mailbox () {
  const messages = []
  var awaiting = undefined

  this.receive = () => {
    if (awaiting) { throw 'Mailbox alread has a receiver'}
    return new Promise((resolve) => {
      if (next = messages.shift()) {
        resolve(next)
      } else {
        awaiting = resolve
      }
    })
  }

  this.deliver = async (message) => {
    messages.push(message)
    if (awaiting) {
      awaiting(messages.shift())
      awaiting = undefined
    }
  }
}

1 个答案:

答案 0 :(得分:0)

async/await使用承诺。实际上,如果您没有承诺await,他们将无济于事。他们不会取代承诺。您通常会在承诺中使用await而不是.then()

让我们看一个简单的例子。假设您有两个返回诺言的函数。

 function delay(t) {
     return new Promise(resolve => {
         setTimeout(resolve, t);
     });
 }

 const rp = require('request-promise');

 function getData(uri) {
     let options = {uri, json: true};
     return rp(options);
 }

现在,您希望从三个不同的URL获取数据,请求之间的延迟为1秒。

常规承诺

使用常规的promise(不进行异步/等待),您可以使用promise链接进行如下操作:

function getAllData() {
    let result = {};
    return getData(firstURL).then(data => {
        results.d1 = data;
        return delay(1000);
    }).then(() => {
        return getData(secondURL);
    }).then(data => {
        results.d2 = data;
        return delay(1000);
    }).then(() => {
       return getData(thirdURL);
    }).then(data => {
       results.d3 = data;
       return results;
    });
}

getAllData().then(result => {
   console.log(result);
}).catch(err => {
   console.log(err);
});

使用异步/等待

使用await,可以简化多个异步操作的顺序,但是那些异步操作仍会使用promise。您只是用.then()替换了一些链接的await操作。

async function getAllData() {
   let result = {};
   result.d1 = await getData(firstURL);
   await delay(1000);
   result.d2 = await getData(secondURL);
   await delay(1000);
   result.d3 = await getData(thirdURL);
   await delay(1000);
   return result;
}

getAllData().then(result => {
   console.log(result);
}).catch(err => {
   console.log(err);
});