承诺内部承诺:从子承诺中返回变量的正确方法是什么? (JS)

时间:2017-05-10 14:31:40

标签: javascript promise

我有这样的功能:

function top() {

  //promise1
  ParentPromise({
    ...some code here...
  }).then(function() {


    //promise2
        ChildPromise({
          ..some code here...
        }).then(function(response) {
         var result = response.result.items;

        });

});

};

我需要以这种方式返回结果值:

var myresult = start();

我怎么能这样做? THX

4 个答案:

答案 0 :(得分:24)

承诺的定义是您无法将result真正地分配给myresult然而,您可以将myresult作为一个承诺,直接解析为调用者的result,但是许多承诺都用于实现此目的。基本思想是在上面的块中的每个函数内部,你应该return链中的下一个Promise。例如:

function top() {

  //promise1
  return ParentPromise({
    ...some code here...
  }).then(function() {


    //promise2
        return ChildPromise({
          ..some code here...
        }).then(function(response) {
         var result = response.result.items;
         return result;

        });

});

};

最后,调用top()的代码不会知道或关心使用1,2或12个链式承诺来获取result。它还能够在任何承诺失败的情况下注册错误回调。

答案 1 :(得分:16)

不太确定这是否适用于原生JS承诺,但是在PromiseKit(快速...我知道,但我很确定这应该有效)我习惯于返回第二个承诺,并且像这样链接:

function top() {
  //promise1
  return ParentPromise({
    ...some code here...
  }).then(function() {
    //promise2
    return ChildPromise({
          ..some code here...
    })
  }).then(function(response) {
    var result = response.result.items;
    // do something with `result`

    return result;
  });
}

top().then(function(result){
  // all done 
});

或者用ES6 / lambda表示法;

function top() {
  return ParentPromise().then(_ => {
    return ChildPromise()
  }).then(response => {
    return response.result.items
  })
}

top().then(items => {
  // all done 
})

答案 2 :(得分:1)

这里面临的挑战是您尝试以同步方式使用异步代码。在处理异步代码时,您需要改变您的想法。

解决这个问题的一种方法是让top()返回ParentPromise,然后使用该promise的返回值的.then()设置变量myresult。

function top() {
  ...
  return ParentPromie;
}
var myresult = ''; // default value until you have resolved your promise
top().then(result => myresult = result);

但是,为了实现这一点,您需要添加代码来解决您的承诺:

var ParentPromise = new Promise(function(resolve) { 
  ... some code...
  var ChildPromise = new Promise(function(){
    ...some code...
  }).then(function(response){
    resolve(response.result.items);
  });
});

答案 3 :(得分:1)

运行以下代码,进行扩展以适合您的特定情况。 请注意,它说明了如何返回Promises,并在处理各种暂挂逻辑之前,之中和之后的各个阶段添加逻辑。

function ParentPromise(){
  // add complexity here, always returning a promise(s)
  // ie Promise.all, new Promise, Promise.reject or whatever...
  // here for simplicity, just return one to resolve with a clear value
  // to see it at the other end
  return Promise.resolve({items:1234});
}
function start() {
  // any method that returns the first promise, kicking off the complexity
  return ParentPromise(/*
    infinitely complex promise-conflation (individual or Promise.all, etc)
    only requirement is that each ***return a promise***
    where each is resolved or rejected
  */)
  .then((result) => {
    // do something with `result`
    console.log(result.items);
    // note returning what we want to come out **next**
    return result;
  });

};

var myresult;

start()
.then((result)=>{ myresult = result; })
.finally(()=>{ console.log('myresult:',myresult); });