How do you properly return multiple values from a promise?

后端 未结 9 1353
慢半拍i
慢半拍i 2020-12-04 14:14

I\'ve recently run into a certain situation a couple of times, which I didn\'t know how to solve properly. Assume the following code:

somethingAsync()
  .the         


        
相关标签:
9条回答
  • 2020-12-04 14:35

    Simply return a tuple:

    async add(dto: TDto): Promise<TDto> {
    console.log(`${this.storeName}.add(${dto})`);
    return firebase.firestore().collection(this.dtoName)
      .withConverter<TDto>(this.converter)
      .add(dto)
      .then(d => [d.update(this.id, d.id), d.id] as [any, string])
      .then(x => this.get(x[1]));
    

    }

    0 讨论(0)
  • 2020-12-04 14:38

    You can't resolve a promise with multiple properties just like you can't return multiple values from a function. A promise conceptually represents a value over time so while you can represent composite values you can't put multiple values in a promise.

    A promise inherently resolves with a single value - this is part of how Q works, how the Promises/A+ spec works and how the abstraction works.

    The closest you can get is use Q.spread and return arrays or use ES6 destructuring if it's supported or you're willing to use a transpilation tool like BabelJS.

    As for passing context down a promise chain please refer to Bergi's excellent canonical on that.

    0 讨论(0)
  • 2020-12-04 14:41

    You can check Observable represented by Rxjs, lets you return more than one value.

    0 讨论(0)
  • 2020-12-04 14:44

    Simply make an object and extract arguments from that object.

    let checkIfNumbersAddToTen = function (a, b) {
    return new Promise(function (resolve, reject) {
     let c = parseInt(a)+parseInt(b);
     let promiseResolution = {
         c:c,
         d : c+c,
         x : 'RandomString'
     };
     if(c===10){
         resolve(promiseResolution);
     }else {
         reject('Not 10');
     }
    });
    };
    

    Pull arguments from promiseResolution.

    checkIfNumbersAddToTen(5,5).then(function (arguments) {
    console.log('c:'+arguments.c);
    console.log('d:'+arguments.d);
    console.log('x:'+arguments.x);
    },function (failure) {
    console.log(failure);
    });
    
    0 讨论(0)
  • 2020-12-04 14:46

    you can only pass one value, but it can be an array with multiples values within, as example:

    function step1(){
      let server = "myserver.com";
      let data = "so much data, very impresive";
      return Promise.resolve([server, data]);
    }
    

    on the other side, you can use the destructuring expression for ES2015 to get the individual values.

    function step2([server, data]){
      console.log(server); // print "myserver.com"
      console.log(data);   // print "so much data, very impresive"
      return Promise.resolve("done");
    }
    

    to call both promise, chaining them:

    step1()
    .then(step2)
    .then((msg)=>{
      console.log(msg); // print "done"
    })
    
    0 讨论(0)
  • 2020-12-04 14:47

    You can return an object containing both values — there's nothing wrong with that.

    Another strategy is to keep the value, via closures, instead of passing it through:

    somethingAsync().then(afterSomething);
    
    function afterSomething(amazingData) {
      return processAsync(amazingData).then(function (processedData) {
        // both amazingData and processedData are in scope here
      });
    }
    

    Fully rather than partially inlined form (equivalent, arguably more consistent):

    somethingAsync().then(function (amazingData) {
      return processAsync(amazingData).then(function (processedData) {
        // both amazingData and processedData are in scope here
      });
    }
    
    0 讨论(0)
提交回复
热议问题