Цепные обещания и передаваемые между ними параметры
Я новичок в Node/Express и пытаюсь использовать Promises для выполнения последовательных API-вызовов Apple CloudKit JS API.
Мне неясно, как поместить функции в последовательность и передать их соответствующие возвращаемые значения из одной функции в другую.
Вот что у меня так далеко:
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)
})
}
Я получаю ошибку в конце: .then(saveRecord(record))
и это говорит record
не определено Я думал, что это так или иначе вернется из предыдущего обещания.
Кажется, что это должно быть проще, чем я, но я в замешательстве. Как я могу получить несколько Обещаний, чтобы связать их вместе, когда у каждого разные resolve
/reject
результаты?
2 ответа
В коде мало вопросов.
Во-первых: вы должны передать функцию .then()
но вы фактически пропускаете результат вызова функции:
.then(saveRecord(record))
Кроме того saveRecord(record)
технически может возвращать функцию, так что возможно иметь такое утверждение, которое кажется вам не подходящим. Так что вам нужно просто
.then(saveRecord)
Другая проблема не возвращает ничего изнутри saveRecord
а также fetchUserRecord
функция также.
И, наконец, вам не нужно возвращать обертки 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){});
}
Не забудьте вернуть преобразованные данные или новое обещание. Иначе undefined
будут возвращены к следующим связанным функциям.
Поскольку @skyboyer помог мне понять, что происходит, я отмечу их ответ как правильный.
Мне пришлось немного подправить вещи, так как мне нужно было передать возвращенные значения последующим функциям в моей цепочке обещаний. Вот где я оказался:
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)
})
})
}