【问题标题】:JS Async/Await vs Promise vs CallbacksJS Async/Await vs Promise vs Callbacks
【发布时间】:2020-12-31 11:22:40
【问题描述】:

我试图了解这 3 个之间的区别。回调和承诺很清楚,但我不了解异步/等待的用法。我知道这是承诺的语法糖,但我尝试过的没有奏效。我正在分享我试图理解这一切的一段代码......

我尝试过使用数组

var array = [1,2,3];

和2个功能

  • get() 在 1 秒内执行并控制台 array
  • post(item) 在 2 秒内执行并在 array 中推送一个新项目

现在,我想要得到的是 post 方法应该首先执行 & get 在它之后,以便控制台上的结果应该是 [1,2,3,4] 而不是 [1,2,3]

回调

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item, callback) {
    setTimeout(() => {
        array.push(item);
        callback();
    }, 2000);
}

function init() {
    post(4, get);
    // returns [1,2,3,4] ✅
}

它工作正常,但如果回调太多,代码会更混乱......所以,

承诺

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

function init() {
    post(4).then(get);
    // returns [1,2,3,4] ✅
}

好的,代码更简洁。但仍然有多个then 呼叫...现在,

异步/等待

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    await post(4);
    get();
    // returns [1,2,3] ❌

    await post(4);
    await get();
    // returns [1,2,3] ❌

    post(4);
    await get();
    // returns [1,2,3] ❌
}

更简洁的版本,但无论哪种方式,它都有效...我也尝试过这个(将两个函数(post 和get)转换为异步并使用then 调用)

async function get() {
    setTimeout(() => console.log(array), 1000);
}

async function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    post(4).then(get);
    // returns [1,2,3] ❌
}

但还是没用。所以我对这个功能(即异步/等待)完全感到困惑。请详细说明这个例子。在同样的情况下,请告诉我Promise.resolve 和Promise.all!谢谢

【问题讨论】:

  • 在将 init 从 .then() 语法更改为 await 糖时,您仍然需要使用返回承诺的 post 函数。

标签: javascript node.js promise async-await callback


【解决方案1】:

async 和 await 是管理承诺

的工具
await post(4);

你在这里等待post返回的promise被解决。

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

但是,post 不返回承诺,所以它没有任何用处。

你之前有一个 post 的工作实现,并带有一个承诺。所以使用它:

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

【讨论】:

  • 这是否意味着async/await 只是.then() 的替代品?
  • 如果我使用Promise.resolve(...)而不是return new Promise((resolve, reject) => ...),它会起作用
  • 大概,不,因为Promise.resolve 返回一个已解决的承诺,所以它会在超时完成之前解决。
【解决方案2】:

您对async 和await 的尝试未使用任何能够在延迟后解决承诺的方法。就目前而言,您定义的所有async 函数都会返回一个立即解析的承诺。

您会想要使用经常使用的实用程序函数。它使用setTimeout返回一个在给定毫秒数后解析的promise:

// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let array = [1, 2, 3];

async function get() {
    await delay(1000);
    console.log(array);
}

async function post(item) {
    await delay(1000);
    array.push(item)
}

async function init() {
    await post(4);
    await get();
}

init();
console.log("wait for it...");

【讨论】:

  • 非常感谢实用功能:)
【解决方案3】:

类似于你在PROMISE中所做的。

将 post setTimeout 包装在一个 Promise 中并返回它。
在 settimeout 的主体内调用 resolve。

function post(item) {
 return new Promise((resolve)=>{
   setTimeout(() => {
     array.push(item)
     resolve()
   }, 2000);
 })
}

那么你可以这样使用它:

async function init() {
    await post(4);
    get();
    }

【讨论】:

  • 太棒了。我长久以来的困惑现在结束了:)
猜你喜欢
  • 2019-04-07
  • 2019-09-16
  • 2017-05-10
  • 2018-10-09
  • 2012-11-02
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 2014-07-19
相关资源
最近更新 更多