简体   繁体   English

链式承诺和它们之间的传递参数

[英]Chaining Promises and Passing Parameters between Them

I'm new to Node/Express and am trying to use Promises to executive successive API calls to Apple's CloudKit JS API. 我是Node / Express的新手,正在尝试使用Promises执行对Apple的CloudKit JS API的连续API调用。

I'm unclear on how to put the functions in sequence and pass their respective return values from one function to the next. 我不清楚如何依次放置函数,并将它们各自的返回值从一个函数传递到下一个。

Here's what I have so far: 这是我到目前为止的内容:

var CloudKit = require('./setup')

//----
var fetchUserRecord = function(emailConfirmationCode){
  var query = { ... }

  // Execute the query
  CloudKit.publicDB.performQuery(query).then(function (response) {
    if(response.hasErrors) {
      return Promise.reject(response.errors[0])
    }else if(response.records.length == 0){
      return Promise.reject('Email activation code not found.')
    }else{
      return Promise.resolve(response.records[0])
    }
  })
}

//-----
var saveRecord = function(record){
  // Update the record (recordChangeTag required to update)
  var updatedRecord = { ... }

  CloudKit.publicDB.saveRecords(updatedRecord).then(function(response) {
    if(response.hasErrors) {
      Promise.reject(response.errors[0])
    }else{
      Promise.resolve()
    }
  })
}

//----- Start the Promise Chain Here -----
exports.startActivation = function(emailConfirmationCode){

  CloudKit.container.setUpAuth() //<-- This returns a promise
  .then(fetchUserRecord) //<-- This is the 1st function above
  .then(saveRecord(record)) //<-- This is the 2nd function above
    Promise.resolve('Success!')
  .catch(function(error){
    Promise.reject(error)
  })

}

I get an error near the end: .then(saveRecord(record)) and it says record isn't defined. 我在结尾处收到一个错误: .then(saveRecord(record)) ,它说未定义record I thought it would somehow get returned from the prior promise. 我认为它将以某种方式从先前的承诺中得到回报。

It seems like this should be simpler than I'm making it, but I'm rather confused. 看起来这应该比我做的要简单,但是我很困惑。 How do I get multiple Promises to chain together like this when each has different resolve / reject outcomes? 当每个人的resolve / reject结果不同时,如何将多个Promises链接在一起?

There are few issues in the code. 代码中几乎没有问题。

First: you have to pass function to .then() but you actually passes result of function invocation: 首先:您必须将函数传递给.then()但实际上您传递了函数调用的结果:

.then(saveRecord(record))

Besides saveRecord(record) technically may return a function so it's possible to have such a statement valid it does not seem your case. 除了saveRecord(record)技术上讲,它可能会返回一个函数,因此有可能使这样的语句有效,这似乎不是您的情况。 So you need just 所以你只需要

.then(saveRecord)

Another issue is returning nothing from inside saveRecord and fetchUserRecord function as well. 另一个问题是在saveRecordfetchUserRecord函数内部什么也不返回。

And finally you don't need to return wrappers Promise.resolve from inside .then : you may return just transformed data and it will be passed forward through chaining. 最后你不需要返回包装Promise.resolve从里面.then :你可以返回刚刚变换的数据,它会向前链接进行传递。

var CloudKit = require('./setup')

//----
var fetchUserRecord = function(emailConfirmationCode){
  var query = { ... }

  // Execute the query
  return CloudKit.publicDB.performQuery(query).then(function (response) {
    if(response.hasErrors) {
      return Promise.reject(response.errors[0]);
    }else if(response.records.length == 0){
      return Promise.reject('Email activation code not found.');
    }else{
      return response.records[0];
    }
  })
}

//-----
var saveRecord = function(record){
  // Update the record (recordChangeTag required to update)
  var updatedRecord = { ... }

  return CloudKit.publicDB.saveRecords(updatedRecord).then(function(response) {
    if(response.hasErrors) {
      return Promise.reject(response.errors[0]);
    }else{
      return Promise.resolve();
    }
  })
}

//----- Start the Promise Chain Here -----
exports.startActivation = function(emailConfirmationCode){

  return CloudKit.container.setUpAuth() //<-- This returns a promise
    .then(fetchUserRecord) //<-- This is the 1st function above
    .then(saveRecord) //<-- This is the 2nd function above
    .catch(function(error){});
}

Don't forget returning transformed data or new promise. 不要忘记返回转换后的数据或新的承诺。 Otherwise undefined will be returned to next chained functions. 否则, undefined将返回到下一个链接函数。

Since @skyboyer helped me figure out what was going on, I'll mark their answer as the correct one. 由于@skyboyer可以帮助我弄清楚发生了什么,因此我会将其答案标记为正确的答案。

I had to tweak things a little since I needed to pass the returned values to subsequent functions in my promise chain. 由于我需要将返回的值传递给我的Promise链中的后续函数,因此我不得不进行一些调整。 Here's where I ended up: 这是我结束的地方:

exports.startActivation = function(emailConfirmationCode){
  return new Promise((resolve, reject) => {

    CloudKit.container.setUpAuth()
      .then(() => {
        return fetchUserRecord(emailConfirmationCode)
      })
      .then((record) => {
        resolve(saveRecord(record))
      }).catch(function(error){
        reject(error)
      })

  })
}

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

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