【问题标题】:Run multiple JavaScript Promises with RSVP.js Promise Library使用 RSVP.js Promise 库运行多个 JavaScript Promise
【发布时间】:2016-01-27 07:56:05
【问题描述】:

下面的简单演示 JavaScript 代码使用 RSVP.js Promise 库 https://github.com/tildeio/rsvp.js/ 使用 AJAX 加载一些 JSON 数据,并在加载完所有 JSON 数据后触发一些代码。

我想扩展它以在 JSON 数据加载后执行更多不是 AJAX 请求的 Promise。

例如,在 JSON 数据加载后,我想创建另一个 Promise,它将运行一个设置一些 DOM 事件处理程序/侦听器的函数。

在设置事件处理的函数之后,我想在事件设置完成后运行其他函数。

我很新,还在学习 Promises,在某些情况下还在学习 JavaScript,所以我可以使用一些帮助。非常感谢在下面和 JSFIddle 上扩展我的示例代码!

我相信,如果展示了如何在我的演示中再添加 1 个 promise,那么我在最终应用中添加任意数量的 promise 就足够了。

JSFIddle Demo代码如下:http://jsfiddle.net/jasondavis/fttzoggj/


var jsonPromiseCache = {};



// AJAX function to load JSON data using Promise()
var getJsonDataPromise = function(url, key) {

  if (!jsonPromiseCache[key]) {
     jsonPromiseCache[key] = new RSVP.Promise(function(resolve, reject){
      // If jsonPromiseCached data is not set then make AJAX requiest to get it


        var client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();

        console.log('---- "client" XMLHttpRequest/AJAX  variable ======= ',client);


        function handler() {
          if (this.readyState === this.DONE) {
            // On AJAX success, resolve() our Promise() and set result to cached variable
            // to avoid duplicate AJAX requests for this jsonCache[key] Data where "key"
            // is used to assign to each AJAX endpoint URL/request of JSON data...
            // (milestones, tasks, users, etc...)
            if (this.status === 200) {
                jsonPromiseCache[key] = this.response;

                console.log('---- jsonPromiseCache['+key+'] ====== ',jsonPromiseCache[key]);

                // Resolve() the Promise() on AJAX success
                resolve(this.response);

            // On AJAX failure, reject() our Promise()
            }else{
                reject(this);
            }
          }
        };

      // If JSON data for this key is already jsonPromiseCached, then return the jsonPromiseCached version
      // instead of making a new AJAX request!
    });
  }
  return jsonPromiseCache[key];
};

// EXAMPLE USAGE DEMO
// usage loading JSON data with AJAX using Promises
var promises = {
    users: getJsonDataPromise('/echo/json/', 'users'),
    task: getJsonDataPromise('/echo/json/', 'task')
};


RSVP.hash(promises)
.then(function(results) {
  console.log('then() function ran on success of loading JSON data');
  console.log(results);
  console.log('results.users', results.users); // print the users JSON results
  console.log('results.task', results.task); // print the task JSON results

  // I want to create another Promise here which will run a function that creates a bunch of DOM Event handlers/listeners and in that function when it is done loading it should fire a success like the above does when JSON data is done loading
})
.finally(function(){
  console.log('finally() function ran on success and failure.... It is always ran!');
})
.catch(function(reason){
  console.log('[ERROR] REASON:',reason.statusText); //if any of the promises fails.
});


更新

我在这里更新了我的 JSFiddle 演示 http://jsfiddle.net/jasondavis/fttzoggj/2 添加了一个新函数 initDomEvents() 并将其添加到 then(initDomEvents) 调用中。我的控制台显示一切都按照我的意愿运行,但是由于某种原因,现在我的错误被触发了

【问题讨论】:

  • 由于每个.then() 调用都会返回一个promise,因此您可以将.then()s 链接到EOF。继续吧!
  • @Bergi 我读到了一些关于它返回来自先前承诺的数据被传递到每个then() 的内容,我有点困惑,因为我不确定我是否想要这样?我也总是准备好它对异步函数调用的意义,以及在我想要在我的 JSON 数据加载后初始化一堆事件的新函数中,所以当我听到异步时,我认为 AJAX 不是 100% 确定我是否会简单地制作我的活动的常规功能并在其中调用resolve()......
  • @Bergi ...继续....关于我的应用程序的一些小信息。它加载各种与项目管理相关的 JSON 数据。接下来,它为任务模式窗口加载一个任务 JSON 数据,在该窗口中,我必须为诸如日期选择器插件、一些用于里程碑的弹出框插件、分配的用户、降价处理等等之类的东西设置各种事件和库。我只是想基本上使用 Promises 以特殊顺序执行此过程的每个部分,以便某些内容不会在其他内容之前加载....
  • @Bergi ...继续...示例在构建任务模式并添加到 DOM 后,有时我的 Datepicker 库会在库完全加载之前运行时抛出错误。跨度>
  • 也许看看my answer to "Aren't promises just callbacks?"。请注意,promise 回调也可以是同步的,你不需要需要返回一个 promise(但你可以,如果你想等待某些东西)。 “设置事件”听起来是同步的,“加载库”是异步的,应该返回一个承诺。

标签: javascript promise rsvp.js


【解决方案1】:

您使用 RSVP 的任何具体原因?我会切换到 jQuery Promises。

var d = $.Deferred;

$.ajax({
 url: url,
 cache: true,
 dataType: 'json',
 success: function(data){
   d.resolve(data);
 },
 error: function(error){
   d.reject();
 }
});

$.when(d).then(function(data){
     //handle
});

【讨论】:

  • 我已经阅读了很多关于 jQuery 如何让 Promises 出错的文章,并且在 jQuery v3 中,他们计划更正并更改它们以使其更符合 ES6,所以我不想使用损坏的样式来更改它一年下来
  • 在使用 RSVP.js 之前,我使用了 jQuery Promises。我还准备了许多评论,其中 RSVP 应该是最好的 Promise 库之一
  • 当我使用 jQuery Promises 时,我实际上更喜欢像你的演示那样调用我自己的 d.resolve(data);,但我一直被告知我不应该因为 jQUery AJAX 调用已经这样做了
  • 它也可以在没有d.resolve(data) 的情况下使用success: function(data){ callback(data) }, error: function(error){ callback(data) } 之类的回调来处理。对于您要在这里完成的工作,我看不到 jQuery 会给您带来任何问题。但是我实际上并没有回答您的问题:| .
【解决方案2】:

我的控制台显示一切都按照我的意愿运行,但是由于某种原因,现在我的错误被触发了

initDomEvents 函数中没有 resolvereject 函数。它们仅作为 new RSVP.Promise(…) 回调的参数提供。尝试调用它们会引发错误,该错误会被捕获并传播到您的错误处理程序(但它没有 .statusText 属性,因此只打印了 undefined)。

正如我在 cmets 中所说,如果您的函数不执行任何异步操作,则无需返回承诺。您只需 return 一个值或 throw 一个异常以及来自您的承诺回调。
如果您坚持围绕您的结果或拒绝创建承诺,您可以使用RSVP.Promise.resolve(…)RSVP.Promise.reject(…) 函数来创建已履行/拒绝的承诺对象。

【讨论】:

  • 我现在也看到我的很多非 ajax 类型代码可以简单地在 then(function(results){ /* non async code */}) 内部调用,而不是作为它自己的 Promise 函数......我在回复 function does nothing asynchronous there is no need to return a promise 时提到了这一点我明白你的意思了,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
相关资源
最近更新 更多