最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Mixing ES6 Promises with JQuery Promises - Stack Overflow

programmeradmin2浏览0评论

I have used $q (Angular.js) and would often return promises within a .then call. The effect was that the next .then call would wait for the previous promise to finish.

I am now using native es6 promises to try to 'promisify' a callback based library and I am unable to do so.

The problem is that the next value in the .then chain is a promise object, rather than the resolved value of that promise. It calls the next .then value before the promise is resolved, simply returning the last return value.

Is there anyway to wait for the previous promise to resolve?

Example:

$.ajax({
    url: "//localhost:3000/api/tokens",
    type: "POST",
    data: JSON.stringify({
      user: {
        email: '[email protected]',
        password: 'password123'
      }
    }),
    contentType: "application/json"
})
.then(data => data.token.encoded)         // OK
.then(token => Farmbot({ token: token })) // OK
.then(function(bot){                      // OK
  return new Promise(function(resolve, reject) {
    bot.connect(function(){ resolve(bot); });
  });
}, errorr)
.then(function(bot){ // NOT OK!
  // passes in an unresolved promise object, which is useless.
  //
  bot; // => {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
});

My question is:

Do ES6 promises wait for the previous .then's promise to resolve?

I have used $q (Angular.js) and would often return promises within a .then call. The effect was that the next .then call would wait for the previous promise to finish.

I am now using native es6 promises to try to 'promisify' a callback based library and I am unable to do so.

The problem is that the next value in the .then chain is a promise object, rather than the resolved value of that promise. It calls the next .then value before the promise is resolved, simply returning the last return value.

Is there anyway to wait for the previous promise to resolve?

Example:

$.ajax({
    url: "//localhost:3000/api/tokens",
    type: "POST",
    data: JSON.stringify({
      user: {
        email: '[email protected]',
        password: 'password123'
      }
    }),
    contentType: "application/json"
})
.then(data => data.token.encoded)         // OK
.then(token => Farmbot({ token: token })) // OK
.then(function(bot){                      // OK
  return new Promise(function(resolve, reject) {
    bot.connect(function(){ resolve(bot); });
  });
}, errorr)
.then(function(bot){ // NOT OK!
  // passes in an unresolved promise object, which is useless.
  //
  bot; // => {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
});

My question is:

Do ES6 promises wait for the previous .then's promise to resolve?

Share Improve this question edited Mar 28, 2016 at 22:58 Rick asked Mar 28, 2016 at 3:49 RickRick 8,8469 gold badges52 silver badges79 bronze badges 1
  • 1 Angular and jQuery don't make particularly good bedfellows. In an angular app you should really be using $http(), not jQuery.ajax() – Roamer-1888 Commented Mar 28, 2016 at 12:49
Add a comment  | 

2 Answers 2

Reset to default 23

The issue stems from trying to use a native Promise within a chain of Deferred promises.

Currently (jQuery 1.8 – 2.x), jQuery's definition of .then() only recognizes the library's own type in its support for chaining.

So, you could return a $.Deferred() promise instead:

// ...
.then(function(bot){
  return $.Deferred(function(defer) {
    bot.connect(function(){ defer.resolve(bot); });
  });
}, errorr)
// ...

Or, you can use Promise.resolve(thenable) to convert the initial $.Deferred() given by $.ajax() to a native Promise so that you're using the native .then() throughout the chain, which will recognize a new Promise() being returned (as well as a $.Deferred()):

Promise.resolve($.ajax({
  // ...
}))
.then(data => data.token.encoded)
// ...

Or, you can try jQuery 3.0, currently in beta:

jQuery.Deferred is now Promises/A+ compatible

jQuery.Deferred objects have been updated for compatibility with Promises/A+ and ES2015 Promises, verified with the Promises/A+ Compliance Test Suite. [...]

With it, your original snippet should work as you expected without any revision.

Do ES6 promises wait for the previous .then's promise to resolve?

Put it this way: an ES6 promise never, ever calls a .then(onFulfilled) function with a promise or thenable object. Onfulfilled listeners are only called with non-promise values.

Converting jQuery "thenable" objects into ES6 Promises before trusting them may solve the problem:

var jqPromise = $.ajax({
    url: "//localhost:3000/api/tokens",
    type: "POST",
    data: JSON.stringify({
      user: {
        email: '[email protected]',
        password: 'password123'
      }
    }),
    contentType: "application/json"
})
.then(data => data.token.encoded)         // OK
.then(token => Farmbot({ token: token })) // OK

; 

var es6Promise = Promise.resolve(jqPromise); // convert to ES6 promise

es6Promise.then(function(bot){                      // OK
  return new Promise(function(resolve, reject) {
    bot.connect(function(){ resolve(bot); });
  });
}, errorr)
.then(function(bot){ // will not pass in unfulfilled promise

  // process bot value

});
发布评论

评论列表(0)

  1. 暂无评论