Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/443.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 模块化承诺和承诺_Javascript_Design Patterns_Promise_Es6 Promise - Fatal编程技术网

Javascript 模块化承诺和承诺

Javascript 模块化承诺和承诺,javascript,design-patterns,promise,es6-promise,Javascript,Design Patterns,Promise,Es6 Promise,我有一系列函数,它们返回我想要实现的广义承诺,所以我这样写它们: function checkWebpageForReference(data){ //checks a webpage for the reference in html var promise = new Promise(function(resolve,reject){ fetchUrl(data.url, function(err, meta, body){ if (e

我有一系列函数,它们返回我想要实现的广义承诺,所以我这样写它们:

function checkWebpageForReference(data){
    //checks a webpage for the reference in html
    var promise = new Promise(function(resolve,reject){
        fetchUrl(data.url, function(err, meta, body){
            if (err) { reject(err); } else {
                console.log(body)
                if (body.toString().indexOf(data.text) !== -1){
                    resolve(data);
                } else {
                    reject("Could not find quote");
                }
            }
        });
    });
    return promise;
}

function takeScreenshot(data){
    //takes a screenshot of a webpage and saves it to the file system
    //TODO: Mouse coordinates
    data.id = shortid.generate();
    data.filename = data.id+'.png';
    var promise = new Promise(function(resolve,reject){
        webshot(data.url, data.filename, { shotOffset: {left: data.mouseX, top: data.mouseY} }, function(err) {
            if (err) { reject(err); } else {
                resolve(data);   
            }
        });
    });
    return promise;
}

function uploadReferencePictureToS3(data){
    //uploads a picture to S3
    var promise = new Promise(function(resolve, reject){
        s3.putObject({
            ACL: 'public-read',
            Bucket: S3_BUCKET,
            Key: data.id,
            Body: data.picturedata,
            ContentType: "image/jpg"
        }, function(err) {
            if (err) { reject(err); } else {
                resolve(data);   
            }
        }); 
    });
    return promise;
}

function saveNewReferenceToDb(data){
    //saves a new Reference to the database
    var promise = new Promise(function(resolve, reject){
        new Reference({
            _id: data.id,
            url: data.url,
            text: data.text,
            screenshot_url: AWS_S3_URL + data.id,
            created_by: "Daniel"
        }).save(function(err, saved){
            if (err) { reject(err); } else {
                data.newReference = saved;
                resolve(data);   
            }
        });
    });
    return promise;
}

function readFile(data){
    //reads a file from the file structure and stores it in a variable
    var promise = new Promise(function(resolve,reject){
        console.log(data);
        fs.readFile(data.filename, function(err, picturedata){
            console.log(picturedata);
            if (err) { reject(err); } else {
                data.picturedata = picturedata;
                resolve(data);   
            }
        }) ;
    });
    return promise;
}

function deleteFile(data){
    //deletes a file from the file structure
    var promise = new Promise(function(resolve, reject){
        fs.unlink(data.filename);
        resolve(data);
    });
    return promise;
}
我解析每个函数中的数据,因为我计划有很多这类函数,我不知道链接时调用它们的顺序:

readfile(somedata)
.then(upload)
.then(delete)
.then(save)
//etc
这很好,直到我必须做承诺。所有:

   Promise.all([
        referenceTools.checkWebpageForReference(req.body),
        referenceTools.takeScreenshot(req.body)
    ])
    .then(function(results){
        utils.readFile(results[1])
        .then(referenceTools.uploadReferencePictureToS3)
        .then(utils.deleteFile)
        .then(referenceTools.saveNewReferenceToDb)
        .then(function(data){
            res.json(data.newReference);
        })
        .catch(function(err){
            utils.errorHandler(err);
            res.send("There was an internal error. Please try again soon.");
        });  
    })
    .catch(function(err){
        utils.errorHandler(err);
        res.send("There was an internal error. Please try again soon.");
    });
    //my very ugly way of doing it
使用
Promise.all().then(upload)
会给我带来错误,因为Promise.all()返回的新Promise是一个包含
checkWebpageForReference
takeScreenshot
两个分辨率的对象。本质上,在
readFile
中,我无法访问
数据
字段,因为生成的承诺是
[数据,数据]

是否有一种模式可以帮助我实现我需要做的事情?我需要做出承诺,为他们提供尽可能多的数据。

你可以像这样对他们进行
.map()

Promise.all(...)
  .then(datas => Promise.all(datas.map(upload)));
由于您是服务器端的,我强烈推荐Bluebird作为本机承诺的替代品。然后你可以做:

Promise.all(...)
  .map(upload);
您可以像这样
.map()
覆盖它们:

Promise.all(...)
  .then(datas => Promise.all(datas.map(upload)));
由于您是服务器端的,我强烈推荐Bluebird作为本机承诺的替代品。然后你可以做:

Promise.all(...)
  .map(upload);

那么,您的每个函数都遵循一些通用接口吗?i、 e.
prf1
prf2
都返回包含
new\u variable1
的对象?如果没有,如果它不知道接收到什么,你如何使
prf3
保持一致?@MattWay他们实际上没有遵循什么模式。我把这留给他们使用链子的时候。我意识到这使得它容易出错,但我还没有找到更好的方法。这些函数只是假设
数据
包含它们要求的字段。如果链条设计得很好,那么它们会的。但我不知道如何将其标准化。你能给出一个例子,说明你希望
prf3
在内部是什么样子的吗?因为你使用的是相同的对象引用作为每个函数的输入,你上面的例子不应该起作用吗?通过抓取
结果[1]
您不是简单地选择了一个[相同的]参考吗?@MattWay它确实有效,但我担心它会在将来引起混乱或问题。如果Promise.all()中的一个函数返回了另一个函数不返回的字段,反之亦然,那么很难知道该怎么做。我想我想要的是一种方法来跟踪在链接承诺时传递下来的变量,同时确保使用承诺时的安全性。那么,您的每个函数都遵循一些公共接口吗?i、 e.
prf1
prf2
都返回包含
new\u variable1
的对象?如果没有,如果它不知道接收到什么,你如何使
prf3
保持一致?@MattWay他们实际上没有遵循什么模式。我把这留给他们使用链子的时候。我意识到这使得它容易出错,但我还没有找到更好的方法。这些函数只是假设
数据
包含它们要求的字段。如果链条设计得很好,那么它们会的。但我不知道如何将其标准化。你能给出一个例子,说明你希望
prf3
在内部是什么样子的吗?因为你使用的是相同的对象引用作为每个函数的输入,你上面的例子不应该起作用吗?通过抓取
结果[1]
您不是简单地选择了一个[相同的]参考吗?@MattWay它确实有效,但我担心它会在将来引起混乱或问题。如果Promise.all()中的一个函数返回了另一个函数不返回的字段,反之亦然,那么很难知道该怎么做。我想我想要的是一种方法来跟踪在链接承诺时传递下来的变量,同时确保在使用承诺时的安全性。所有注意这将等待每一步的进展。通常,先映射后Promise.all会更快,允许对每个文件并行运行所有步骤。例如:
Promise.all(files.map(file=>readfile(file)‌​atas=>…)
注意,这会等待每一步的进度。通常,先映射后Promise.all会更快,允许对每个文件并行运行所有步骤。例如:
Promise.all(files.map(file=>readfile(file)‌​atas=>…)