运行 在 node.js 中依次执行多个异步函数
running multiple async functions sequentially in node.js
我是 javascript 和 node.js 环境的新手。
我很难使用回调。因为当我有很多程序
连在一起,很难写,会变得很讨厌。
所以,在我 google 找到答案后,我找到了异步工具,但它仍然 运行 喜欢
它可以使用回调逐块执行代码。
例如,f1 -> f2 -> f3 ...
但是,我们的服务器和我的电脑总是有延迟。
然后如果我做了一些事情,比如创建桶,然后打印我得到了多少。
它会在我添加一个之后打印出原始数量的桶。
同样的情况,比如删除存储桶....有大神能帮帮我吗
谢谢...
function bucketSerialTesting(s3)
{
async.series([
function f1(callback)
{
settingBucket ('testjsbucket2',s3);
callback('1');
}
,
function f2(callback)
{
settingBucket('testjsbucket3', s3);
callback('2');
}
,
function f3(callback)
{
listBucket(s3);
callback('3');
}
,
function f4(callback)
{
deleteBucket('testjsbucket2', s3);
callback('4');
}
,
function f5(callback)
{
deleteBucket('testjsbucket3', s3);
callback('5');
}
,
function f6(callback)
{
listBucket(s3);
callback('6');
},
],
function(err, results){
console.log(results);
});
}
function settingBucket (bucketName, s3){
var s3 = new AWS.S3();
var params = {
Bucket: bucketName, /* required */
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
}).on('success',function(response)
//put bucket cors for browsers javascript testing
{
var params = {
Bucket: bucketName, /* required */
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*',],
AllowedMethods: ['GET','PUT','DELETE','POST'],
AllowedOrigins: ['*','null'],
ExposeHeaders: ['ETag',],
},
]
},
};
s3.putBucketCors(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('put bucketcors succeed');
}
});
}).send();
}
function listBucket(s3)
{
s3.listBuckets(function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('we have '+data.Buckets.length.toString()+' buckets');
for (var i = data.Buckets.length - 1; i >= 0; i--) {
console.log(data.Buckets[i].Name);
};
} // successful response
});
}
function deleteBucket(bucketName, s3){
var params = {
Bucket: bucketName, /* required */
};
s3.listObjectVersions(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data);
params = {Bucket: bucketName};
params.Delete = {};
params.Delete.Objects = [];
console.log(data.Versions.length);
for(j = 0; j < data.Versions.length;++j)
{
params.Delete.Objects.push({Key: data.Versions[j].Key,
VersionId: data.Versions[j].VersionId
});
}
for(j = 0; j < data.DeleteMarkers.length;++j)
{
params.Delete.Objects.push({Key: data.DeleteMarkers[j].Key,
VersionId: data.DeleteMarkers[j].VersionId
});
}
s3.deleteObjects(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
}
params = {Bucket: bucketName};
s3.deleteBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
});
}
});
}
一个选项是 Q promises,它确实有助于解除回调地狱并稍微扁平化您的代码。
https://github.com/kriskowal/q
延迟 resolve/reject 模式很适合您。
下面是一个扁平化异步工作的示例。它打印一个文件 hello.txt(存在),等待一秒钟,在不存在的文件上出现错误,跳转到失败处理程序,然后运行 finally.
var Q = require('q');
var fs = require('fs');
var path = require('path');
// a promise just defers execution of success or failure - must return the promise. notice how it calls resolve in the callback of the async function.
var wait = function(ms) {
var defer = Q.defer();
console.log('waiting ' + ms + ' ms');
setTimeout(function() {
defer.resolve();
}, ms);
return defer.promise;
}
// you can wrap a node callback function with Q.defer and call reject or resolve
var getFileContents = function(path) {
var defer = Q.defer();
fs.readFile(path, function(err, data) {
if (err) {
defer.reject(err);
}
else {
// can't pass multiple args back - it returns one obj
defer.resolve({ path: path, data: data });
}
});
return defer.promise;
}
var ms = 1000;
var printFile = function(filePath) {
// even function wrapping up work returns a promise so it can be
// connected with another outer sequence of work
return wait(ms)
.then(function() {
console.log(new Date().toString());
})
.then(function() {
// if you call async that returns promise, you must return it
return getFileContents(filePath);
})
// the resolve data from previous promise is passed as input to next then
.then(function(contents) {
console.log(contents.path + ':');
console.log(contents.data.toString());
})
}
// sometimes you need to just return a no op based on a conditional check etc...
var noOpPromise = function() {
console.log('no op');
return Q(null);
}
printFile(path.join(__dirname, 'hello.txt'))
.then(function() {
// throw new Error('throwing will jump to fail');
return wait(1000);
})
.then(function() {
return printFile(path.join(__dirname, 'noexist.txt'));
})
.then(function() {
console.log('should never get here');
})
// can also use .catch
.fail(function(err) {
console.error('Error: ' + err.message);
})
.fin(function() {
console.log('done with work');
})
function bucketSerialTesting(s3)
{
Q.fcall(function f1()
{
return settingBucket ('testjsbucket20',s3);
})
.then(function f2()
{
return settingBucket('testjsbucket30', s3);
}
)
.then(function f3()
{
return listBucket(s3);
}
)
.then(function f4()
{
return deleteBucket('testjsbucket20', s3);
}
)
.then(function f4()
{
return deleteBucket('testjsbucket30', s3);
}
)
.then(function f4()
{
return listBucket(s3);
}
)
.done();
}
function settingBucket (bucketName, s3){
var deferred = Q.defer();
var s3 = new AWS.S3();
var params = {
Bucket: bucketName, /* required */
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
}).on('success',function(response)
//put bucket cors for browsers javascript testing
{
var params = {
Bucket: bucketName, /* required */
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*',],
AllowedMethods: ['GET','PUT','DELETE','POST'],
AllowedOrigins: ['*','null'],
ExposeHeaders: ['ETag',],
},
]
},
};
s3.putBucketCors(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('put bucketcors succeed');
deferred.resolve(data);
}
});
}).send();
return deferred.promise;
}
function listBucket(s3)
{
var deferred = Q.defer();
s3.listBuckets(function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('we have '+data.Buckets.length.toString()+' buckets');
for (var i = data.Buckets.length - 1; i >= 0; i--) {
console.log(data.Buckets[i].Name);
};
deferred.resolve(data);
} // successful response
});
return deferred.promise;
}
function deleteBucket(bucketName, s3){
var deferred = Q.defer();
var params = {
Bucket: bucketName, /* required */
};
s3.listObjectVersions(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data);
params = {Bucket: bucketName};
params.Delete = {};
params.Delete.Objects = [];
// console.log(data.Versions.length);
for(j = 0; j < data.Versions.length;++j)
{
params.Delete.Objects.push({Key: data.Versions[j].Key,
VersionId: data.Versions[j].VersionId
});
}
for(j = 0; j < data.DeleteMarkers.length;++j)
{
params.Delete.Objects.push({Key: data.DeleteMarkers[j].Key,
VersionId: data.DeleteMarkers[j].VersionId
});
}
s3.deleteObjects(params, function(err, data) {
if (err) {
console.log(err, err.stack);
console.log('or has no objects');// an error occurred
}
else {
console.log(data);
}
params = {Bucket: bucketName};
s3.deleteBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
deferred.resolve(data);
}
});
});
}
});
return deferred.promise;
}
我是 javascript 和 node.js 环境的新手。 我很难使用回调。因为当我有很多程序 连在一起,很难写,会变得很讨厌。
所以,在我 google 找到答案后,我找到了异步工具,但它仍然 运行 喜欢 它可以使用回调逐块执行代码。 例如,f1 -> f2 -> f3 ...
但是,我们的服务器和我的电脑总是有延迟。 然后如果我做了一些事情,比如创建桶,然后打印我得到了多少。 它会在我添加一个之后打印出原始数量的桶。 同样的情况,比如删除存储桶....有大神能帮帮我吗
谢谢...
function bucketSerialTesting(s3)
{
async.series([
function f1(callback)
{
settingBucket ('testjsbucket2',s3);
callback('1');
}
,
function f2(callback)
{
settingBucket('testjsbucket3', s3);
callback('2');
}
,
function f3(callback)
{
listBucket(s3);
callback('3');
}
,
function f4(callback)
{
deleteBucket('testjsbucket2', s3);
callback('4');
}
,
function f5(callback)
{
deleteBucket('testjsbucket3', s3);
callback('5');
}
,
function f6(callback)
{
listBucket(s3);
callback('6');
},
],
function(err, results){
console.log(results);
});
}
function settingBucket (bucketName, s3){
var s3 = new AWS.S3();
var params = {
Bucket: bucketName, /* required */
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
}).on('success',function(response)
//put bucket cors for browsers javascript testing
{
var params = {
Bucket: bucketName, /* required */
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*',],
AllowedMethods: ['GET','PUT','DELETE','POST'],
AllowedOrigins: ['*','null'],
ExposeHeaders: ['ETag',],
},
]
},
};
s3.putBucketCors(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('put bucketcors succeed');
}
});
}).send();
}
function listBucket(s3)
{
s3.listBuckets(function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('we have '+data.Buckets.length.toString()+' buckets');
for (var i = data.Buckets.length - 1; i >= 0; i--) {
console.log(data.Buckets[i].Name);
};
} // successful response
});
}
function deleteBucket(bucketName, s3){
var params = {
Bucket: bucketName, /* required */
};
s3.listObjectVersions(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data);
params = {Bucket: bucketName};
params.Delete = {};
params.Delete.Objects = [];
console.log(data.Versions.length);
for(j = 0; j < data.Versions.length;++j)
{
params.Delete.Objects.push({Key: data.Versions[j].Key,
VersionId: data.Versions[j].VersionId
});
}
for(j = 0; j < data.DeleteMarkers.length;++j)
{
params.Delete.Objects.push({Key: data.DeleteMarkers[j].Key,
VersionId: data.DeleteMarkers[j].VersionId
});
}
s3.deleteObjects(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
}
params = {Bucket: bucketName};
s3.deleteBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
});
}
});
}
一个选项是 Q promises,它确实有助于解除回调地狱并稍微扁平化您的代码。
https://github.com/kriskowal/q
延迟 resolve/reject 模式很适合您。
下面是一个扁平化异步工作的示例。它打印一个文件 hello.txt(存在),等待一秒钟,在不存在的文件上出现错误,跳转到失败处理程序,然后运行 finally.
var Q = require('q');
var fs = require('fs');
var path = require('path');
// a promise just defers execution of success or failure - must return the promise. notice how it calls resolve in the callback of the async function.
var wait = function(ms) {
var defer = Q.defer();
console.log('waiting ' + ms + ' ms');
setTimeout(function() {
defer.resolve();
}, ms);
return defer.promise;
}
// you can wrap a node callback function with Q.defer and call reject or resolve
var getFileContents = function(path) {
var defer = Q.defer();
fs.readFile(path, function(err, data) {
if (err) {
defer.reject(err);
}
else {
// can't pass multiple args back - it returns one obj
defer.resolve({ path: path, data: data });
}
});
return defer.promise;
}
var ms = 1000;
var printFile = function(filePath) {
// even function wrapping up work returns a promise so it can be
// connected with another outer sequence of work
return wait(ms)
.then(function() {
console.log(new Date().toString());
})
.then(function() {
// if you call async that returns promise, you must return it
return getFileContents(filePath);
})
// the resolve data from previous promise is passed as input to next then
.then(function(contents) {
console.log(contents.path + ':');
console.log(contents.data.toString());
})
}
// sometimes you need to just return a no op based on a conditional check etc...
var noOpPromise = function() {
console.log('no op');
return Q(null);
}
printFile(path.join(__dirname, 'hello.txt'))
.then(function() {
// throw new Error('throwing will jump to fail');
return wait(1000);
})
.then(function() {
return printFile(path.join(__dirname, 'noexist.txt'));
})
.then(function() {
console.log('should never get here');
})
// can also use .catch
.fail(function(err) {
console.error('Error: ' + err.message);
})
.fin(function() {
console.log('done with work');
})
function bucketSerialTesting(s3)
{
Q.fcall(function f1()
{
return settingBucket ('testjsbucket20',s3);
})
.then(function f2()
{
return settingBucket('testjsbucket30', s3);
}
)
.then(function f3()
{
return listBucket(s3);
}
)
.then(function f4()
{
return deleteBucket('testjsbucket20', s3);
}
)
.then(function f4()
{
return deleteBucket('testjsbucket30', s3);
}
)
.then(function f4()
{
return listBucket(s3);
}
)
.done();
}
function settingBucket (bucketName, s3){
var deferred = Q.defer();
var s3 = new AWS.S3();
var params = {
Bucket: bucketName, /* required */
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
}).on('success',function(response)
//put bucket cors for browsers javascript testing
{
var params = {
Bucket: bucketName, /* required */
CORSConfiguration: {
CORSRules: [
{
AllowedHeaders: ['*',],
AllowedMethods: ['GET','PUT','DELETE','POST'],
AllowedOrigins: ['*','null'],
ExposeHeaders: ['ETag',],
},
]
},
};
s3.putBucketCors(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('put bucketcors succeed');
deferred.resolve(data);
}
});
}).send();
return deferred.promise;
}
function listBucket(s3)
{
var deferred = Q.defer();
s3.listBuckets(function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
console.log('we have '+data.Buckets.length.toString()+' buckets');
for (var i = data.Buckets.length - 1; i >= 0; i--) {
console.log(data.Buckets[i].Name);
};
deferred.resolve(data);
} // successful response
});
return deferred.promise;
}
function deleteBucket(bucketName, s3){
var deferred = Q.defer();
var params = {
Bucket: bucketName, /* required */
};
s3.listObjectVersions(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data);
params = {Bucket: bucketName};
params.Delete = {};
params.Delete.Objects = [];
// console.log(data.Versions.length);
for(j = 0; j < data.Versions.length;++j)
{
params.Delete.Objects.push({Key: data.Versions[j].Key,
VersionId: data.Versions[j].VersionId
});
}
for(j = 0; j < data.DeleteMarkers.length;++j)
{
params.Delete.Objects.push({Key: data.DeleteMarkers[j].Key,
VersionId: data.DeleteMarkers[j].VersionId
});
}
s3.deleteObjects(params, function(err, data) {
if (err) {
console.log(err, err.stack);
console.log('or has no objects');// an error occurred
}
else {
console.log(data);
}
params = {Bucket: bucketName};
s3.deleteBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
console.log(data);
deferred.resolve(data);
}
});
});
}
});
return deferred.promise;
}