JS异步/等待vs承诺vs回调

时间:2020-09-13 15:23:14

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

我试图理解这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] ✅
}

它可以正常工作,但是如果回调太多,代码将变得更加混乱……所以,

PROMISE

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] ❌
}

更干净的版本,但都无效,它起作用了……我也尝试过此操作(将两个函数(postget都转换为异步并使用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.resolvePromise.all的信息!谢谢

3 个答案:

答案 0 :(得分:3)

asyncawait管理承诺

的工具
await post(4);

在这里,您正在等待post返回的诺言得到解决。

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

但是,post 不会返回承诺,因此它没有任何用处。

您之前有一个承诺,post的有效实施。因此使用:

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

答案 1 :(得分:2)

您尝试使用asyncawait时,不会使用任何在延迟后可以解决承诺的方法。就目前而言,您定义的所有async函数都会返回立即解决的Promise。

您将要使用经常使用的实用程序功能。它使用setTimeout返回承诺,该承诺在给定的毫秒数后解析:

// 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...");

答案 2 :(得分:1)

类似于您在 PROMISE 中所做的事情。

将setTimeout放入Promise中并返回。
在settimeout主体内调用resolve。

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

然后您可以像这样使用它:

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