应该在同步功能中避免承诺吗?

时间:2018-01-09 10:00:42

标签: javascript node.js asynchronous promise

我目前正在尝试美化一些NodeJS遗留代码,并且这样就提出了这个问题,我找不到任何最佳实践或指导(如果你知道的话,请与我分享)。< / p>

目的是不要简单地看到一个人可以通过Promises组合同步和异步代码(这很清楚),但是为什么一个人应该例如如果清除了函数的同步处理,则转到同步代码。这意味着简单地将Promise添加到同步代码中会有什么缺点?有吗?例如。在运行时,或者更重要的是,在异步流程中?

E.g。以下示例为异步函数:

Foo.prototype.addNode = function addNode() {
  var self = this;
  return new Promise(function (resolve, reject) {
    var node = new Node(self.getNodes().getLastId() + 1);
    resolve (self.getNodes().add(node));
  });
}

在我们的业务逻辑中,此函数应该确实是异步,因为这是在promise链中递归调用的。

然而,函数 add 是同步处理的,因为这是一个通用元素的简单Array.push(),并且有一些验证。

GenericElementList.prototype.add = function add(T) {
  if (this.T.length === 0) {
    this.T.push(T);
    this.typeOfT = T.constructor;
    return this;
  }
  else {
    if (!(T.constructor === this.typeOfT)){
      this.T.push(T);
      return this;
    }
    else {
      throw new IllegalArgumentError('Invalid type of element to push into array! Was: ' + T.constructor.name + ' but should be: ' + this.typeOfT.name + '!');
    }
  }
};

(为避免混淆:self.getNodes()返回Node元素GenericElementGenericElementListGenericElement的列表数据结构。 )

现在我的问题是:如果我们要向add - 函数添加一个Promise,那么在这些方法的异步处理中是否存在运行时或流程流的任何缺点?有没有理由避免这种情况?或者唯一的缺点是某些样板代码?

1 个答案:

答案 0 :(得分:0)

在javascript / node中,无论你如何表达,同步执行都会保持同步。举个例子

console.log("stage 1")
findIndex(data, 2, (err, index)=>{
    console.log(err, index)
})
console.log("stage 3")

function findIndex (arr, val, callback){
    console.log("stage 2")
    var idx =arr.indexOf(val)
    if(idx==-1) return callback(new Error("value not found"))
    return callback(null, idx)
}

虽然异步或可以说I / O绑定执行始终是异步的。无论你如何表达它(有些人认为es6 async / await使异步执行同步)

console.log("stage 1")
setTimeout(()=>{
    console.log("stage 2")
}, 0)
console.log("stage 3")

打开你的js控制台,找到差异和执行流程

承诺也遵循同样的事情

现在循环中的异步函数

  
      
  1. 顺序迭代在异步任务依赖时很有用。 (一个操作的结果需要提供其他(/ s))
  2.   
(function loop(i) {
if(i==4) return
setTimeout(function() {
  console.log('Working on index', i);
  loop(++i)
 }, 1000);
})(0);
  
      
  1. 当异步任务彼此独立时,并行执行很有用。
  2.   
var data = [1,2,3,4]
data.map(val=>{
    return new Promise((resolve, reject) => {
        setTimeout(function() {
         console.log('Working on index', val);
         // pass data in reslove() and get when promise resloved
        })
    });
})
Promise.all(data)
.then(done=>{
    // get passed data
    console.log(done);
})
.catch(err=>{
    console.log(err);
})

获得更多 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise