簡體   English   中英

鏈式命令總是按順序執行嗎?

[英]Are chained commands always executed in order?

在node.js中編碼(這是異步的)時,我可以依賴我的鏈式命令按順序執行嗎?

var x=new MyObject();
x.start().doAThing().stop()

將先start運行,然后是doAThing然后stop

這取決於這些功能正在做什么。 除非您使用回調,否則命令將按順序執行。 但是,如果start()函數的邏輯需要異步調用,則只有在調用完成后結果才可用。 這意味着后續的doAThing()函數不能在start()函數中使用異步調用的結果。

tl; dr技術上,是的,但如果鏈中的某些函數是異步的,您可能需要考慮以不同方式組織代碼。


例如,序列x.start().doAThing().stop()中的每個方法都是一個方法調用,它需要一些對象來操作。 為了調用doAThing() ,JavaScript VM必須首先評估x.start() ,然后查找doAThing函數,然后它才能開始執行doAThing的主體。

什么會doAThing做可以根據價值是完全不同的x.start()

MyObject.prototype.start = function () {
  if (/* condition */) {
    return {
      doAThing: function () {
        return {
          stop: function () {
            console.log('path1');
          }
        };
      }
    };
  }
  else {
    return {
      doAThing: function () {
        return {
          stop: function () {
            console.log('path2');
          }
        };
      }
    };
  }
};

但是,您的函數可以啟動可能無序發生的異步任務。

MyObject.prototype.start = function () {
  setTimeout(function () {
    // This will happen out-of-order, usually after `stop` returns!
    console.log('timed out');
  }, 0);

  return {
    doAThing: function () {
      return {
        stop: function () {
          console.log('stop');
        }
      };
    }
  };
};

請參閱jsbin 輸出:

stop
timed out

如果必須鏈接異步函數,則使用回調,promise或生成器重寫代碼。 例如,承諾:

var start = function (obj) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      // This will happen in order.                                            
      console.log('timed out');
      resolve(obj);
    }, 0);
  });
};

var doAThing = function (obj) {
  return Promise.resolve(obj);
};

var stop = function (obj) {
  // Synchronous functions are fine, too.                                      
  console.log('stop');
};

該鏈將按順序執行這些功能:

Promise.resolve(x)
  .then(start)
  .then(doAThing)
  .then(stop);

輸出:

timed out
stop

從技術上講,答案總是肯定的。 x.start()着火時,如果它執行io操作,Node的運行時將創建一個線程來執行該操作,因此異步,start仍然立即被觸發, x.start().doAThing()將在x.start()返回時x.start() 但是,asynch io可以在函數返回后返回響應,因此如果它是異步的, .doAThing()將不會有響應。 這就是asynch函數使用回調/ promises / ES7異步函數的原因,技術上也可以使用ES6生成器,它可以訪問io響應。 只要它不是io操作,Nodejs就是同步。

所以

function start(){
    var a = 1 + 1;
    return {
        doAthing: function(){ return a;}
    };
}

將完全同步。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM