为什么我的JavaScript Promises使用RSVP.js库在我的所有Promises成功后返回错误?

时间:2015-10-27 19:40:50

标签: javascript promise rsvp.js

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

之后,它在链式then()调用

中运行非ajax函数

我的所有承诺都是成功的,但它最后也会返回错误!

我不确定为什么会运行错误?

JSFiddle演示:http://jsfiddle.net/jasondavis/fttzoggj/3/

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];
};

新的非ajax承诺

// testing a  non ajax Promise
function initDomEvents() {
    var eventsLoaded = true;

    //if (eventsLoaded) {
        jsonPromiseCache['domevents'] = eventsLoaded;

        console.log('---- initDomEvents() ran');

        // Resolve() the Promise() 
        //resolve(jsonPromiseCache['domevents']);
        resolve();

        // On false, reject() our Promise()
    //}else{
    //    reject();
    //}

};

示例使用演示

// 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
})
.then(initDomEvents)
.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.
});

更新

这个新的演示http://jsfiddle.net/jasondavis/fttzoggj/6/增加了第3个Promise,而第3个则没有运行!第二个Promise函数initDOmEvents()现在返回此错误...

ERROR] REASON: ReferenceError: resolve is not defined
    at initDomEvents (http://fiddle.jshell.net/_display/:91:9)
    at G (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:6009)
    at F (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:5928)
    at L (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:6661)
    at MutationObserver.h (http://apollowebstudio.com/labs/js/sugarcrm-pm/js/rsvp.min.js:2:1667)

新增代码......

//测试非ajax Promise

function initTaskModalLibraries() {
    var taskModalScriptsLoaded = true;

    if (taskModalScriptsLoaded) {
        jsonPromiseCache['inittaskmodallibraries'] = taskModalScriptsLoaded;

        console.log('---- initTaskModalLibraries() ran');

        // Resolve() the Promise() 
        //resolve(jsonPromiseCache['domevents']);
        resolve();

        // On false, reject() our Promise()
    }else{
        reject();
    }

};

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
})
.then(initDomEvents)
.then(initTaskModalLibraries)
.finally(function(){
  console.log('finally() function ran on success and failure.... It is always ran!');
})
.catch(function(reason){
  console.log('[ERROR] REASON:',reason); //if any of the promises fails.
});

更新2

我现在在新的非ajax函数中看到我缺少new RSVP.Promise(function(resolve, reject){})

修正了演示http://jsfiddle.net/jasondavis/fttzoggj/8/

1 个答案:

答案 0 :(得分:1)

在[错误]日志行中,删除.statusText,如下所示:

.catch(function(reason){
  console.log('[ERROR] REASON:',reason); //if any of the promises fails.
});

你会看到这个可点击的错误:

[ERROR] REASON:
ReferenceError: resolve is not defined       initDomEvents()/_display/ (line 92)
G()                                          rsvp.min.js (line 2)
F()                                          rsvp.min.js (line 2)
L()                                          rsvp.min.js (line 2)
h()                                          rsvp.min.js (line 2)

这是updated fiddle,我认为这符合您的意图。主要变化是:

return new RSVP.Promise(initDomEvents)  

在你的第一个then处理程序中,它将返回的结果传递给下一个then(链接),

并更改initDomEvents的方法签名:

function initDomEvents(resolve, reject) {

以便定义解析/拒绝。