最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to return from a promise inside then block? - Stack Overflow

programmeradmin2浏览0评论

I'm trying to understand how promise's cascading properly works. For this, I created a function which returns a new Promise but has some callback functions in their scope:

exports.function1 = (params) => {
  return new Promise((resolve, reject) => {
    // do something sync

    someFunctionAsyncWithCallback(params, (err, data) => { //async func
      err ? reject(err) : resolve(data);
    })
  }).then(data => {
     // do something sync again

    anotherAsyncFunctionWithCallback(data, function (err, response) {
      return err ? Promise.reject(err) : Promise.resolve(response);
      // return err ? reject(err) : resolve(response); ?
    });
  })
}

Inside then block, how can I made a properly return in order to continue cascading process? In executor there are resolve/reject functions which I can call in order to continue chaining. But, once we are in then execution, these function aren't there - correct me if I'm wrong - and I don't know how to move on.

Any ment will be appreciated.

I'm trying to understand how promise's cascading properly works. For this, I created a function which returns a new Promise but has some callback functions in their scope:

exports.function1 = (params) => {
  return new Promise((resolve, reject) => {
    // do something sync

    someFunctionAsyncWithCallback(params, (err, data) => { //async func
      err ? reject(err) : resolve(data);
    })
  }).then(data => {
     // do something sync again

    anotherAsyncFunctionWithCallback(data, function (err, response) {
      return err ? Promise.reject(err) : Promise.resolve(response);
      // return err ? reject(err) : resolve(response); ?
    });
  })
}

Inside then block, how can I made a properly return in order to continue cascading process? In executor there are resolve/reject functions which I can call in order to continue chaining. But, once we are in then execution, these function aren't there - correct me if I'm wrong - and I don't know how to move on.

Any ment will be appreciated.

Share Improve this question asked Feb 19, 2018 at 13:33 guijobguijob 4,4883 gold badges22 silver badges41 bronze badges 1
  • Just call another function from inside then() which cascades with resolve, reject?? – Ryan Wilson Commented Feb 19, 2018 at 13:35
Add a ment  | 

3 Answers 3

Reset to default 5

Avoid bining promise chains with callback-style APIs. Instead, wrap the callback-style API with a promise wrapper, which then lets you pose things reasonably.

The examples you've quoted look like NodeJS APIs. If you're using Node, v8 and higher have utils.promisify which can be used to quickly and easily wrap standard NodeJS-callback-style functions to functions returning promises.

// Get promise-enabled versions:
const promiseSomeFunctionAsyncWithCallback = utils.promisify(someFunctionAsyncWithCallback);
const promiseAnotherAsyncFunctionWithCallback = utils.promisify(anotherAsyncFunctionWithCallback);

// Use them:
exports.function1 = (params) => {
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(promiseAnotherAsyncFunctionWithCallback);
  })
};

If you're not using Node, or you're using an old version, there's nothing magic about utils.promisify, you can easily roll your own:

const promisify = f => return function(..args) {
    return new Promise((resolve, reject) => {
        f.call(this, ...args, (err, result) => {
            if (err) {
                reject(err);
            } else {
                resolve(result);
            }
        });
    });
};

Re your ment:

I have some sync code between these callback functions.. How would you handle it in your first example?

There are two styles for that:

1. Put the sync code in the then callback and chain only when you reach your next async bit:

exports.function1 = (params) => {
  // Code here will run synchronously when `function1` is called
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(result => {
        // You culd have synchronous code here, which runs when
        // this `then` handler is called and before we wait for the following:
        return promiseAnotherAsyncFunctionWithCallback(result);
    });
  })
};

2. Put the sync code in its own then callback:

exports.function1 = (params) => {
  // Code here will run synchronously when `function1` is called
  return promiseSomeFunctionAsyncWithCallback(params)
    .then(result => {
        // You culd have synchronous code here, which runs when
        // this `then` handler is called.
        // Pass on the result:
        return result;
    })
    .then(promiseAnotherAsyncFunctionWithCallback);
  })
};

One advantage to #2 is that each distinct logical step is its own block. It does mean one additional yield back to the microtask loop at the end of this iteration of the main event loop, but that's not likely to be an issue.

You need to return another Promise:

return new Promise((res, rej) => anotherAsyncFunctionWithCallback(data, (err, data) => err ? rej(err) : res(data));

However then it would make sense to promisify the function:

 const promisify = f => (...args) => new Promise((res, rej) => f(...args, (err, data) => err? rej(err) : res(data)));

const asyncF = promisify(AsyncFunctionWithCallback);

So one can do:

asyncF(1).then(asyncF).then(console.log);

you can use a flag variable for returning something.

example;

async function test(){
   let flag=0;
   await fetch(request).then(()=> flag=1}
   if(flag==1) return;
}
发布评论

评论列表(0)

  1. 暂无评论