promises如何保证在异步操作之后执行'resolve'函数

var*_*max 1 javascript promise

我有这个代码:

var myFirstPromise2 = new Promise((resolve, reject) => {
    //setTimeout models an operation that takes a long time
    setTimeout(function(){console.log('finishTimeout')},60000);
    resolve('success');
});

myFirstPromise2.then((successMessage) => {
    console.log('yay '+successMessage);
});
Run Code Online (Sandbox Code Playgroud)

输出是:

yay success 
finishTimeout
Run Code Online (Sandbox Code Playgroud)

我希望resolve()在冗长的操作完成后执行,以便输出反转.

我也对一般的承诺感到困惑.上面的代码与简单地执行此操作没有区别:

setTimeout(function(){console.log('finishTimeout')},60000);
console.log('yay success');
Run Code Online (Sandbox Code Playgroud)

编辑:放入resolve()内部之间的区别是什么setTimeout:

setTimeout(function() {
    console.log('finishTimeout')
    console.log("yay success")
},60000)
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 5

promises如何保证在异步操作之后执行'resolve'函数

他们没有. Promise只是一个通知和错误传播系统.它们仅在某些代码调用解析promise时resolve()解析promise.resolve()在异步操作实际完成之前,您不应该调用.如果您resolve()过早打电话(就像您正在做的那样),承诺将在异步操作完成之前过早解决.

这里的代码在回调实际触发resolve()之前setTimeout()调用,因此承诺很快得到解决:

var myFirstPromise2 = new Promise((resolve, reject) => {

  //setTimeout models an operation that takes a long time
  setTimeout(function(){console.log('finishTimeout')},60000);
  resolve('success');
});
Run Code Online (Sandbox Code Playgroud)

该代码应该是在setTimeout()回调内部调用resolve的情况,因此在计时器触发之后才会解析promise:

var myFirstPromise2 = new Promise((resolve, reject) => {

  //setTimeout models an operation that takes a long time
  setTimeout(function(){
      console.log('finishTimeout');
      resolve('success');
  },60000);
});
Run Code Online (Sandbox Code Playgroud)

注意:resolve()仅在实际执行异步操作时调用.您的版本在异步操作完成之前调用它,因此在您的版本中,承诺在异步操作完成之前很快得到解决.

Promise没有任何神奇的力量可以知道异步操作何时完成.它们只完成您的代码告诉他们要做的事情.因此,只有resolve()在异步操作实际完成时才调用.


编辑:在setTimeout中放置解决方案之间的区别是什么:

setTimeout(function() {
    console.log('finishTimeout')
    console.log("yay success")
},60000);
Run Code Online (Sandbox Code Playgroud)

在这个具体的例子中,这将工作得很好.Promise用作异步操作的组织和管理工具.当您有多个需要排序或协调的异步操作时,它们非常有用,在编写涉及多个异步操作的强大错误处理时它们非常有用.你真的不需要一个简单的单一计时器操作的承诺.

但是,一旦你开始使用promises用于高价值用途,你会发现它们只是设计和编码所有异步操作的更好方法,即使是更简单的操作.您会发现几乎每次异步操作都要使用它们.您没有必要,但我的经验是,一旦您开始使用它们,将它们用于所有异步操作会更容易和更简单.

注意:从技术上讲,这与之间存在细微差别:

setTimeout(function() {
    console.log('finishTimeout')
    console.log("yay success")
},60000);
Run Code Online (Sandbox Code Playgroud)

还有这个:

var myFirstPromise2 = new Promise((resolve, reject) => {

  //setTimeout models an operation that takes a long time
  setTimeout(function(){
      console.log('finishTimeout');
      resolve('success');
  },60000);
});

myFirstPromise2.then((successMessage) => {
    console.log('yay '+successMessage);
});
Run Code Online (Sandbox Code Playgroud)

因为所有.then()处理程序都在下一个刻度线上执行,所以console.log()在第二个代码示例中的两个操作与第一个代码示例之间的延迟将稍长(以毫秒为单位).这可能不是很重要,但既然你问到了差异是什么,我想我会指出那个微小的差别.有一些实际的原因可以解释为什么它是这样设计的,这总体上是一个很好的设计决策(在.then()调用处理程序之前堆栈是解开的,解析一致是异步的,即使promise同步解决等等).