简体   繁体   English

应该由Promise调用同步代码。然后创建一个新的Promise

[英]Should synchronous code called by Promise .then create a new Promise

I've implemented some code, where asynchronous code is followed by some synchronous functions. 我已经实现了一些代码,其中异步代码后跟一些同步函数。 For example: 例如:

function processSomeAsyncData() {
  asyncFuncCall()
    .then(syncFunction)
    .catch(error);
}

If I understand correctly then is also a Promise. 如果我理解正确, then也是一个承诺。 Then, should I create a promise in the synchronous code as well? 那么,我应该在同步代码中创建一个承诺吗?

function syncFunction() {
  const p = new Promise (function (resolve, reject) {
    //Do some sync stuff
    ...
    resolve(data);
  }
  return p;
}

If that isn't necessary, how do you reject the promise from the synchronous code if an error occurred? 如果没有必要,如果发生错误,如何拒绝同步代码中的承诺?

You don't need to create a new promise explicitly. 您无需显式创建新承诺。 There is an easier way. 有一种更简单的方法。

This example is contrived because it will never fail, but the point is that you don't have to create a promise and you don't have to return a resolve(val). 这个例子是设计的,因为它永远不会失败,但关键是你不必创建一个promise,你不必返回一个解析(val)。

function syncFunction() {
  var j = "hi"
  if(j){
    return j;
  }
  return new Error('i am an error');
}

This will work: 这将有效:

asyncFunction()
  .then(syncFunction);

But if you did it the other way around: 但如果你这样做了反过来:

syncFunction()
  .then(asyncFunction);

You would have to define your syncFunction as: 您必须将syncFunction定义为:

function syncFunction() {

  var j = "hi"
  return new Promise((resolve, reject) => {
    if(j){
      return resolve(j);
    }
    return reject('error');
  })  
}

Edit: To prove to all you non believers out there, give this guy a shot locally on your computer. 编辑:为了向所有非信徒证明,在你的电脑上给这个家伙一个机会。 Proves that you have these many options available to you. 证明您有这么多选项可供您使用。 :) :)

var Promise = require('bluebird');


function b(h) {
    if(h){
        return h;
    }
    return Promise.resolve('hello from b');
}

function a(z) {
    return new Promise((resolve, reject)=> {
        if(z){return resolve(z)};
        return resolve('hello from a');
    })
}

a().then(b).then(x => console.log(x)).catch(e => console.log(e));
b().then(a).then(x => console.log(x)).catch(e => console.log(e));

No. Synchronous functions may be called from synchronous code and should always fail synchronously! 不可以。同步功能可以从同步代码中调用,并且应该始终同步失败! They need not conform to asynchronous callers in any way. 它们不需要以任何方式符合异步调用者。 If an error occurs just throw an error. 如果发生错误,则抛出错误。 Try it: 试试吧:

 var asyncFuncCall = () => Promise.resolve(); function syncFunction() { throw new Error("Fail"); } asyncFuncCall() .then(syncFunction) .catch(e => console.log("Caught: " + e.message)); 

This works because an exception thrown by a function passed to a .then is converted to a rejection of the promise it is supposed to return. 这是有效的,因为传递给.then的函数抛出的异常被转换为拒绝它应该返回的promise。

Additionally, any value returned by a function passed to a .then is converted to a promise resolved with that value. 此外,传递给.then的函数返回的任何值都将转换为使用该值解析的promise。 The promise code calling the function takes care of this. 调用该函数的promise代码负责这一点。

This lets you mix synchronous and asynchronous code without problems: 这使您可以毫无问题地混合同步和异步代码:

asyncFuncCallOne()
  .then(() => {
    var x = syncFunction();
    return asyncFuncCallTwo(x);
  })
  .catch(e => console.log(e.message));

It's optional. 这是可选的。

If you return a promise from the syncFunction , then your original promise will resolve only after the new promise resolves and any value returned by the new promise will be passed to the next then in the chain. 如果您在返回一个承诺syncFunction ,那么你当初的诺言将仅解析后的新承诺解决,并通过新的承诺返回的值将被传递到下一个then在链。

If you return a non-Promise value, that will be passed to the next then in the chain. 如果返回非承诺值,将被传递到下一个then在链。

To reject from within syncFunction , just throw an exception. 要从syncFunction拒绝,只需抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM