关于node.js:构造Javascript的最佳方法如果语句在函数中是同步的

Best way of structuring Javascript If statements to be synchronous in a function

我问这个问题所以我可以学习用javascript做某事的'最佳实践'方式。 说我在这里有这个代码:

1
2
3
4
5
6
7
8
var someFunc = function () {
  if (something) {
    // do something
  }
  if (somethingElse) {
    // do somethingElse
  }
};

问题是什么是确保在'somethingElse'之前始终运行'某事'的最佳方法。 由于javascript是异步的,我知道我需要某种回调系统来确保这一点。 但是,有没有更简单的方法来重构这个? 如果有很多if语句怎么办? 什么是最好的图书馆干净利落地做这样的事情? 提前致谢。


并非所有代码行都在Javascript中异步运行。这取决于你的代码。例如:

1
2
3
4
5
6
7
8
var someFunc = function () {
  if (something) {
    console.log('something');
  }
  if (somethingElse) {
    console.log('something else');
  }
};

将始终写出以下输出:

1
2
something
something else

但是,如果不是打印值,而是调用稍后将运行的函数(如Ajax请求或setTimeout回调),则无法保证代码以正确的顺序运行。此行为取决于您调用的函数。例如,JQuery $.get()函数是异步的(这意味着它将在以后调用您的函数,而不是在您的控件中),如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
var someFunc = function () {
  if (something) {
    $.get('some-file.txt').done(function (result) {
      console.log(result);
    });
  }
  if (somethingElse) {
    $.get('some-other-file.txt').done(function (result) {
      console.log(result);
    });
  }
};

结果输出可以是任何其他输出中的'some-file.txt'和'some-other-file.txt'的内容。

根据经验,每当您将函数传递给另一个函数(回调)时,您可能正在使用Javascript的异步功能。

嵌套回调

解决此问题的一种方法是在第一个函数中调用第二个异步调用:

1
2
3
4
5
6
7
8
9
10
11
12
var someFunc = function () {
  if (something) {
    $.get('some-file.txt').done(function (result1) {
      console.log(result1);
      if (somethingElse) {
        $.get('some-other-file.txt').done(function (result2) {
          console.log(result2);
        });
      }
    });
  }
};

但是你可能已经猜到了这段代码很难读懂。

承诺救援

使用Promises,您可以拥有更易于阅读的代码。

让我们用promises编写上面丑陋的代码:

1
2
3
4
5
6
7
8
9
10
11
var someFunc = function () {
  if (something) {
    $.get('some-file.txt').then(function (result1) {
      console.log(result1);
      if (somethingElse) {
        return $.get('some-other-file.txt');
      }
    }).then(function (result2) {
        console.log(result2);
    });
};

通常,promises使代码更具可读性并避免过多的嵌套回调。你可以链接promises,它会像同步代码一样读,但它实际上是异步运行的。

请参阅以下问题以获取更多信息:

  • 如何使用jQuery promises链接三个异步调用?
  • Jquery承诺链

承诺的收获是什么?

  • 旧浏览器不支持它们(但您可以使用第三方库添加它们,如ES6 Promise Polyfill。
  • 在承诺被正式标准化之前,每个库都有自己的实现,这些实现略微不兼容(jQuery,Angular,Ember)
  • 它们是一个新的学习概念,因此对于新手来说,学习曲线会有点陡峭。

  • Javascript不是异步的。

    如果满足if条件,则第一个if中的内容将首先执行,然后执行第二个if的内容。