如何将同步函数链接到与promises异步运行?

时间:2015-10-08 00:08:42

标签: javascript jquery node.js asynchronous

我认为尚未在电路板上讨论过这个问题。我一直在研究与承诺链接,我发现你可以将承诺链接到特定的延期者。这允许通过 then 语句注册的所有函数都可以从我读过的内容中异步调用。但是,这假设这些函数是异步写入的。例如,如果我有以下内容:

function asyncEvent() {
  var dfd = jQuery.Deferred();
  dfd.resolve( "start" );
  return dfd.promise();
}

$.when( asyncEvent() ).then(
  function( status ) {
    console.log(status);
    setTimeout(function(){console.log("1");},1000);
  }
).then(function (status) {
	setTimeout(function(){console.log("2");},1000);
});

部分内容取自jquery's documentation

在显示状态后,控制台将按顺序输出1和2。这不是在状态之后显示1秒,而是在1之后显示2秒。因此,此方法不适用于链接同步功能。

我知道有很多方法可以更改每个然后的退货承诺。但是,我的问题是,承诺是否可以在then语句中隐式更改,或者您是否必须使用以下代码(这是我能想到的唯一方法)?如果是这样,您能否向我展示执行此操作的代码的简化版本,因为我不认为this页面上的代码实际上是这样做的。

请注意,当then中的函数返回时,创建的延迟变量d将保留在作用域链中。如果可能的话,我想避免这种情况。最好不要在第一时间创建它。

function asyncEvent() {
  var dfd = jQuery.Deferred();
  dfd.resolve( "start" );
  return dfd.promise();
}

$.when( asyncEvent() ).then(
  function( status ) {
	  var d=$.Deferred();
	  console.log(status);
	  setTimeout(function(){console.log("1");d.resolve();},1000);
	  return d.promise();
  }
).then(function (status) {
	  setTimeout(function(){console.log("2");},1000);
});

部分内容取自jquery's documentation修改 我知道setTimeout实际上并不是同步处理的,但从输出的角度来看也可能是同步处理。

3 个答案:

答案 0 :(得分:0)

  

如何将同步函数链接到异步运行   承诺?

     

但是,我的问题是,承诺是否可以在内部隐含地改变   然后声明或你必须使用如下代码(这是   我能想到的唯一方法吗?

     

请注意,创建的延迟变量d在范围链中保留   然后返回的函数。我想避免这种情况   可能的。

如果要求链接同步功能,请尝试使用.queue()$.queue().queue()允许链接.promise("queueName"),当所有``queueName'函数调用

时,可以在.then() jQuery promise对象上调用"queueName"

var fns = [
    function asyncEvent(next) {
      var msg = "start";
      // push `msg` to `this.status` array
      this.status.push(msg);
      console.log(msg);
      // call `next` function in queue
      next();
    },
    function(next) {
      var msg = "1";
      setTimeout(function() {
        // push `msg` to `this.status` array
        this.status.push(msg);
        console.log(msg);
        // call `next` function in queue
        next()
      }.bind(this), 1000);
    },
    function(next) {
      var msg = "2";
      setTimeout(function() {
        // push `msg` to `this.status` array
        this.status.push(msg);
        console.log(msg);
        // call `next` function in queue
        next()
      }.bind(this), 1000);
    }
  ]
 
, obj = {
    status: []
  };
// set `"queueName"` , call `.queue()` with array of functions `fns` as parameter
$(obj).queue("status", fns)
.dequeue("status")
// do stuff when all `"queueName"` functions called
.promise("status")
.then(function() {
  console.log("complete", this[0].status)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

答案 1 :(得分:0)

嗯,您不应该访问.then返回的承诺,但是您已经看到,您可以在此.then内创建新承诺,并附上回调在解决这个新的承诺时,下一个.then执行,我在附加的stackoverflow帖子中写的实现中看到,承诺总是由另一个名为Defer的实体解决,实际上你不需要创建由于承诺可以自行解决,因此延迟实例,如果您看到Promises on MDN的文档,您将看到构造函数接收到用于解析/拒绝承诺本身的执行函数,因此您可以使用以下内容: / p>

new Promise(function (resolve, reject) {
  // do something async and then reject/resolve itself
  setTimeout(function () {
    resolve()
  }, 1000)
})

您的示例可以使用此构造函数编写,如下所示:

new Promise(function (resolve) {
  resolve('start')
})
  .then(function (status) {
    return new Promise(function (resolve, reject) {
      console.log(status)
      // do something async and then reject/resolve itself
      setTimeout(function () {
        console.log(1)
        resolve()
      }, 1000)
    })
  })
  .then(function () {
    setTimeout(function () {
      console.log(2)        
    }, 1000)
  })

要记住的是,在履行/拒绝承诺后,您无法更改承诺的状态,如果您想根据.then的内容链接功能,请务必返回保证,如果附加到原始承诺的sa .then,当.then中创建的承诺得到履行/拒绝时,它将被执行

仅供参考,以上是:

的快捷方式
  new Promise (function (resolve) {
    resolve('start')
  })
    .then(function (status) {
      return new Promise (function (resolve, reject) {
        console.log(status)
        setTimeout(function () {
          console.log(1)
          resolve()
        }, 1000)
      })
        .then(function () {
          setTimeout(function () {
            console.log(2)
          }, 1000)
        })
    })

答案 2 :(得分:0)

可能这就是你要找的东西

A