承诺不等待解决

时间:2017-04-19 02:51:37

标签: javascript promise

我刚刚听说过承诺,听起来很有希望(好吧,我离开了)。

我希望以下代码显示:
- initVariables之前 - 在initVariables - someName之前 - 在initVariables - someName之前 - initElements之后

但我得到了:
- initVariables之前 - initVariables之前 - initVariables之前 - initElements

之后

有人帮我吗? :-)
大家好! :d

var url = "https://opendata.paris.fr/api/records/1.0/search/?dataset=stations-velib-disponibilites-en-temps-reel&rows=100&facet=banking&facet=bonus&facet=status&facet=contract_name"

var test = Object.create(MyTestClass);
console.log(test.testVariable);

let loadVariables = new Promise(function(resolve, reject) {
  test.initVariables(url);
  resolve(test);
  console.log(test.testVariable);
});

loadVariables.then(function(test){
  test.initElements();
});
console.log(test.testVariable);

MyTestClass定义为:

var MyTestClass = {

    testVariable: "before initVariables",

    initVariables: function(url) {
        $.getJSON(url, function (result) {
            this.testVariable += " - " + result.records[0].fields.name;
        });
    },

    initElements: function() {
        this.testVariable += " - after initElements";
    }
}

3 个答案:

答案 0 :(得分:4)

承诺立即运行。他们立即解决/拒绝的唯一方法是,如果您在其中执行某些操作(例如致电$.getJSON),则只能根据resolve/reject的回调来调用$.getJSON

function getJSONP(url) {
  return new Promise(function(resolve, reject) {
     $.getJSON(url, resolve);
  }
}

function getJSONP(url) {
  return new Promise(function(resolve, reject) {
    $.getJSON(url, function(result) { 
       resolve(result);
    });
  }
}

让它更清晰

然后你可以做

 getJSONP(someURL).then(function(result) {
   console.log(result);
 });

答案 1 :(得分:0)

Promise构造函数不是必需的,因为$.getJSON()返回一个公开.then函数的jQuery promise对象。

问题$.getJSON()处的函数未返回

javascriptthisjqxhr jQuery promise对象,除非设置为context$.ajax()次调用。您可以使用Function.prototype.bind()$.proxy()this设置为.then()链接到test.initVariables,其中$.getJSON(url)调用是从函数返回的。



var MyTestClass = {

  testVariable: "before initVariables",

  initVariables: function(url) {
    return $.getJSON(url)
  },

  handleResult: function(result) {
    this.testVariable += " - " + result.records[0].fields.name;
    console.log(this.testVariable);
  },

  initElements: function() {
    this.testVariable += " - after initElements";
    console.log(this.testVariable)
  }
}

var url = "https://opendata.paris.fr/api/records/1.0/search/?dataset=stations-velib-disponibilites-en-temps-reel&rows=100&facet=banking&facet=bonus&facet=status&facet=contract_name";

var test = Object.create(MyTestClass);

console.log(test.testVariable);

var loadVariables = test.initVariables(url);

loadVariables
.then($.proxy(test.handleResult, test))
.then($.proxy(test.initElements, test))
.fail(function(jqxhr, textStatus, errorThrown) {
  console.log(textStatus, errorThrown);
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

为了解释观察到的结果,预期结果缺少异步操作的效果。以下是一些可能有用的规则:

  1. 创建新承诺时,Promise执行程序函数称为 同步 。在new Promise( executor)语句或表达式之后继续执行时,执行函数已返回。

  2. 通过在promise上调用thencatch方法提供的Promise反应处理程序,在一个线程中执行 异步 在他们被召唤的承诺之后,他们自己已经解决了。

  3. 假设在发生HTTP GET操作后,$.getJSON请求回拨 异步

  4. 浏览代码:

    //**  The top of code executing in a thread, say "T1":
    
    var url = "https://www.example.com"
    
    var test = Object.create(MyTestClass);
    //** here test.testVariable inherits "before initVariables"
    
    console.log(test.testVariable);
    
    let loadVariables = new Promise(function(resolve, reject) {
      test.initVariables(url);
    //** here an asynchronous $getJSON request has been initiated but not completed
    
      resolve(test);
    //**  here the Promise has been synchronously fulfilled,
    //**  during execution of this executor function,  with the test object.
    
      console.log(test.testVariable);
    
    //** here test.testVariable inherits "before initVariables"
    //**  because we are still running synchronously in thread "T1" from the top.
    
    });
    
    loadVariables.then(function(test){
      test.initElements();
    //** this is some time later, not in thread "T1", because
    //** then and catch callbacks are made asynchronously.
    
    });
    console.log(test.testVariable);
    
      // here thread "T1" is still executing,
      // testVariable has not been updated yet.
    

    请注意,使用test对象同步履行创建的承诺最终无用。等待GET请求回调结果数据需要重新考虑采取的方法。