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

Jan*_*art 9 javascript node.js es6-promise

我已经实现了一些代码,其中异步代码后跟一些同步函数.例如:

function processSomeAsyncData() {
  asyncFuncCall()
    .then(syncFunction)
    .catch(error);
}
Run Code Online (Sandbox Code Playgroud)

如果我理解正确then也是一个承诺.我是否应该在同步代码中创建一个承诺?

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

如果没有必要,如果发生错误,如何拒绝同步代码中的承诺?

Pat*_*ard 8

您无需显式创建新承诺.有一种更简单的方法.

这个例子是设计的,因为它永远不会失败,但关键是你不必创建一个promise而你不必返回一个res(val).

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

这将有效:

asyncFunction()
  .then(syncFunction);
Run Code Online (Sandbox Code Playgroud)

但如果你这样做了反过来:

syncFunction()
  .then(asyncFunction);
Run Code Online (Sandbox Code Playgroud)

您必须将syncFunction定义为:

function syncFunction() {

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

编辑:为了向所有非信徒证明,在你的电脑上给这个家伙一个机会.证明您有这么多选项可供您使用.:)

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));
Run Code Online (Sandbox Code Playgroud)

  • 在你的第二个例子中,`new Promise`不需要,应该使用`Promise.resolve`和`Promise.reject`函数. (3认同)
  • @nils是的,从`then`处理程序返回非promise值是完全有效的.请参阅[this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Chaining):_"从onFulfilled或onRejected回调函数返回的值**将自动包装在已解决的承诺中**"_ (3认同)

jib*_*jib 5

不。同步函数可以从同步代码中调用,并且应该总是同步失败!它们不需要以任何方式符合异步调用者。如果发生错误,只需抛出错误。尝试一下:

var asyncFuncCall = () => Promise.resolve();

function syncFunction() {
  throw new Error("Fail");
}

asyncFuncCall()
  .then(syncFunction)
  .catch(e => console.log("Caught: " + e.message));
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为传递给 a 的函数抛出的异常被.then转换为拒绝它应该返回的承诺。

此外,传递给 a 的函数返回的任何值.then都将转换为使用该值解析的承诺。调用该函数的 Promise 代码会处理这个问题。

这使您可以毫无问题地混合同步和异步代码:

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