Node js中Promise是同步还是异步

Posted

技术标签:

【中文标题】Node js中Promise是同步还是异步【英文标题】:Promise is synchronous or asynchronous in node js 【发布时间】:2018-09-29 09:08:55 【问题描述】:

我对承诺有很多困惑。是同步的还是异步的?

return new Promise (function(resolved,reject)
    //sync or async? 
);

【问题讨论】:

Asynchronous 【参考方案1】:

我不认为其他答案是准确的。

new Promise (executor_function)

这里的executor_function将作为Promise初始化的一部分立即运行---这意味着Promise init将同步执行,但并不意味着executor_function内部的代码一定会同步运行,相反,executor_function内部的代码也可以异步运行,例如:

new Promise ((resolve, reject) => 
    setTimeout(resolve, 1000); // wait 1s 
)

【讨论】:

【参考方案2】:

const promise = new Promise(function(resolve, reject) 
  //doing some logic it gonna be executed synchronously
 console.log("check")
  resolve("fullfiled")
)
promise.then(v => 
  console.log(v)
)
console.log("global log")

【讨论】:

【参考方案3】:

这段代码更清楚:

        console.log("0");
        new Promise((resolve, reject) => 
          console.log("1");
          resolve();
        ).then(() => 
          console.log("2");
        );
        console.log("3");

代码打印: 0 1 3 2 所以,then 异步运行,而主回调函数同步运行。

【讨论】:

【参考方案4】:

Promise 就像 javascript 中的普通类。假设您正在创建自己的 Promise 实现,您的 Promise 类大致如下所示。请注意,在您的构造函数中,您期望传递一个方法,您可以立即调用该方法,并将 resolve and reject 作为参数传递。

class Promise 
    constructor(method) 
        method(resolve, reject)
    

    resolve()  ... 

    reject()  ... 

    then()  ... 

所以当您执行new Promise() 时,您只是在创建一个新对象。您的Promise constructor 将运行,它会立即调用该方法。这就是为什么你的 Promise 中的代码会同步执行的原因。

return new Promise (function(resolved,reject)
    //sync or async? 
);

如果您在函数内部调用另一个本质上是异步的函数,那么另一个函数将异步执行,否则,其他所有函数都会同步执行。

如果你有使用then 的promise 链,那么它只会在你的第一个promise 调用resolve() 之后被调用。

return new Promise (function(resolve,reject)
  const a = 5*5; // sync operation.
  db.save(a, function callback()  // async operation.
    resolve() // tells promise to execute `then` block.
  );
);

【讨论】:

【参考方案5】:

当你创建一个 Promise 并将一个回调传回给它时 该回调将立即执行(同步)

const promise= new Promise(function(resolve, reject) 
      //doing some logic it gonna be executed synchronously
       console.log("result");
    )
    console.log("global log")
    

但是当你通过 .then() 方法解决它时,它将以异步方式运行 例如:

const promise = new Promise(function(resolve, reject) 
  //doing some logic it gonna be executed synchronously

  resolve("fullfiled")
)
promise.then(v => 
  console.log(v)
)
console.log("global log")

【讨论】:

【参考方案6】:

Promise 本身并不完全同步或异步。当您创建一个 Promise 时,您传递给它的回调会立即执行,并且在该函数产生之前没有其他代码可以运行。考虑以下示例:

new Promise(function(resolve, reject) 
  console.log('foo');
)
console.log('bar');

promise 外部的代码必须等待 promise 内部的代码(同步)完成才能开始执行。

也就是说,Promise 是处理异步代码的常用方法。 Promise 最常见的用例是表示以异步方式生成或获取的某个值。依赖于该值的逻辑可以通过使用.then() 或相关的 Promise 方法注册回调来异步等待该值可用。

【讨论】:

同步意味着代码只能在上一个任务/代码行完成后才能运行。异步意味着两段代码可以并行运行。承诺之外的代码 DOES NOT 必须等待承诺内的代码完成,除非您使用 await 语法等待它,它将异步转换为同步。 正如您从示例中看到的那样,promise 外部的代码实际上会等待 promise 内部的代码在执行之前产生 yield。 Promise 本质上不是异步的,它们只是表示可能由异步过程生成的值的一种方式。 当然,很公平。我仍然觉得这句话很难理解“依赖于该值的逻辑可以异步等待”。我认为该值是同步等待的 - 这正是同步的意思,在其他代码完成之前无法执行代码。【参考方案7】:

传入 Promise 构造函数的函数同步运行,但任何依赖于其解析的函数都将被异步调用。即使 promise 立即解析,任何处理程序都将异步执行(类似于您 setTimeout(fn, 0) 时) - 主线程首先运行到最后。

无论您的 Javascript 环境如何 - 无论您使用的是 Node 还是浏览器,这都是正确的。

console.log('start');
const myProm = new Promise(function(resolve, reject) 
  console.log('running');
  resolve();
);
myProm.then(() => console.log('resolved'));
console.log('end of main block');

【讨论】:

但根据 Mozilla 网站,您传入的函数是异步的。请参阅以“通常情况下,它的工作方式如下:tetherFunction 中的操作......”开头的段落。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 它指的是convert a callback API to a Promise的通常方式,在这种情况下,在tetherFunction内部调用一个异步的、基于回调的函数,当该回调运行时,resolve被调用。 不错!你可能想把它放在你的答案中,因为这让很多人感到困惑。 更准确地说,传递给 Promise 构造函数的函数会立即(同步)运行,但函数内部的代码是异步运行的。

以上是关于Node js中Promise是同步还是异步的主要内容,如果未能解决你的问题,请参考以下文章

进击Node.js基础

Node.js Promise对象(解决回调地狱问题)async和await函数

node.js中的forEach是同步还是异步

node.js中的forEach是同步还是异步

node.js中的forEach是同步还是异步

node.js 中的回调是始终异步还是始终同步?或者它们可以是“有时是一个,有时是另一个”?