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

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

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

【问题讨论】:

标签: javascript node.js asynchronous promise synchronous


【解决方案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 构造函数的函数会立即(同步)运行,但函数内部的代码是异步运行的。
            猜你喜欢
            • 1970-01-01
            • 2016-11-08
            • 2019-01-17
            • 2017-06-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多